下面列出了org.objectweb.asm.Opcodes# LRETURN 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
static boolean isExitOpcode(int opcode) {
switch(opcode) {
case Opcodes.RET:
case Opcodes.ATHROW:
case Opcodes.RETURN:
case Opcodes.IRETURN:
case Opcodes.LRETURN:
case Opcodes.FRETURN:
case Opcodes.DRETURN:
case Opcodes.ARETURN: {
return true;
}
default: {
return false;
}
}
}
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;
}
}
/**
* Returns a return bytecode instruction suitable for the given return Jandex Type. 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 Jandex Type.
* @return the correct bytecode return instruction for that return type descriptor.
*/
public static int getReturnInstruction(Type jandexType) {
if (jandexType.kind() == Kind.PRIMITIVE) {
switch (jandexType.asPrimitiveType().primitive()) {
case BOOLEAN:
case BYTE:
case SHORT:
case INT:
case CHAR:
return Opcodes.IRETURN;
case DOUBLE:
return Opcodes.DRETURN;
case FLOAT:
return Opcodes.FRETURN;
case LONG:
return Opcodes.LRETURN;
default:
throw new IllegalArgumentException("Unknown primitive type: " + jandexType);
}
} else if (jandexType.kind() == Kind.VOID) {
return Opcodes.RETURN;
}
return Opcodes.ARETURN;
}
/** Inserts the appropriate INVOKESTATIC call */
@Override
public void visitInsn(int opcode) {
if ((opcode == Opcodes.ARETURN)
|| (opcode == Opcodes.IRETURN)
|| (opcode == Opcodes.LRETURN)
|| (opcode == Opcodes.FRETURN)
|| (opcode == Opcodes.DRETURN)) {
throw new RuntimeException(
new UnmodifiableClassException("Constructors are supposed to return void"));
}
if (opcode == Opcodes.RETURN) {
super.visitVarInsn(Opcodes.ALOAD, 0);
super.visitMethodInsn(
Opcodes.INVOKESTATIC,
"com/google/monitoring/runtime/instrumentation/ConstructorInstrumenter",
"invokeSamplers",
"(Ljava/lang/Object;)V",
false);
}
super.visitInsn(opcode);
}
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());
}
}
}
@Override
public void visitInsn(int opcode) {
if ((opcode == Opcodes.ARETURN) || (opcode == Opcodes.IRETURN)
|| (opcode == Opcodes.LRETURN)
|| (opcode == Opcodes.FRETURN)
|| (opcode == Opcodes.DRETURN)) {
throw new RuntimeException(new UnmodifiableClassException("Constructors are supposed to return void"));
}
if (opcode == Opcodes.RETURN) {
super.visitVarInsn(Opcodes.ALOAD, 0);
super.visitTypeInsn(Opcodes.NEW, Type.getInternalName(ScottReportingRule.class));
super.visitInsn(Opcodes.DUP);
super.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(ScottReportingRule.class), "<init>", "()V", false);
super.visitFieldInsn(Opcodes.PUTFIELD,
className, "scottReportingRule",
Type.getDescriptor(ScottReportingRule.class));
}
super.visitInsn(opcode);
}
@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;
}
}
/**
* 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(int opcode) {
switch (opcode) {
case Opcodes.IRETURN:
case Opcodes.LRETURN:
case Opcodes.FRETURN:
case Opcodes.DRETURN:
case Opcodes.ARETURN:
case Opcodes.RETURN:
checkState(mv != null, "Encountered a second return it would seem: %s", opcode);
mv = null; // Done: we don't expect anything to follow
return;
default:
super.visitInsn(opcode);
}
}
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());
}
}
/**
* 针对不同类型返回指令不一样
*
* @param typeS
* @return
*/
private static int getReturnTypeCode(String typeS) {
if ("Z".equals(typeS)) {
return Opcodes.IRETURN;
}
if ("B".equals(typeS)) {
return Opcodes.IRETURN;
}
if ("C".equals(typeS)) {
return Opcodes.IRETURN;
}
if ("S".equals(typeS)) {
return Opcodes.IRETURN;
}
if ("I".equals(typeS)) {
return Opcodes.IRETURN;
}
if ("F".equals(typeS)) {
return Opcodes.FRETURN;
}
if ("D".equals(typeS)) {
return Opcodes.DRETURN;
}
if ("J".equals(typeS)) {
return Opcodes.LRETURN;
}
return Opcodes.ARETURN;
}
@Override
public void visitInsn(int opcode) {
switch (opcode) {
case Opcodes.MONITORENTER:
mBuilder.setUsesConcurrency();
break;
case Opcodes.ARETURN:
case Opcodes.IRETURN:
case Opcodes.LRETURN:
case Opcodes.DRETURN:
case Opcodes.FRETURN:
if (identityState == IdentityMethodState.LOADED_PARAMETER) {
mBuilder.setIsIdentity();
}
sawReturn = true;
break;
case Opcodes.RETURN:
sawReturn = true;
break;
case Opcodes.ATHROW:
if (stubState == StubState.INITIALIZE_RUNTIME) {
sawStubThrow = true;
} else if (justSawInitializationOfUnsupportedOperationException) {
sawUnsupportedThrow = true;
} else {
sawNormalThrow = true;
}
break;
default:
break;
}
resetState();
}
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;
}
}
private void instrumentToTrackReturn(int opcode) {
if (!VariableType.isReturnOperation(opcode)) {
return;
}
if (Opcodes.RETURN == opcode) {
super.visitLdcInsn(lineNumber);
super.visitLdcInsn(methodName);
super.visitLdcInsn(Type.getType("L" + className + ";"));
super.visitMethodInsn(Opcodes.INVOKESTATIC, instrumentationActions.trackerClass, "trackReturn", "(ILjava/lang/String;Ljava/lang/Class;)V", false);
} else {
if (opcode == Opcodes.DRETURN || opcode == Opcodes.LRETURN) {
super.visitInsn(Opcodes.DUP2);
} else {
super.visitInsn(Opcodes.DUP);
}
final VariableType variableType;
if (opcode == Opcodes.IRETURN) {
variableType = VariableType.getReturnTypeFromMethodDesc(desc);
} else {
variableType = VariableType.getByReturnOpCode(opcode);
}
super.visitLdcInsn(lineNumber);
super.visitLdcInsn(methodName);
super.visitLdcInsn(Type.getType("L" + className + ";"));
super.visitMethodInsn(Opcodes.INVOKESTATIC, instrumentationActions.trackerClass, "trackReturn", "(" + variableType.desc + "ILjava/lang/String;Ljava/lang/Class;)V", false);
}
}
private void mutatePrimitiveLongReturn() {
if (shouldMutate("primitive long", "x + 1")) {
super.visitInsn(Opcodes.LCONST_1);
super.visitInsn(Opcodes.LADD);
super.visitInsn(Opcodes.LRETURN);
}
}
private static Map<String, String> checkMethods(ClassNode classNode, Set<String> names) {
Map<String, String> validGetters = Maps.newHashMap();
@SuppressWarnings("rawtypes")
List methods = classNode.methods;
String fieldName = null;
checkMethod:
for (Object methodObject : methods) {
MethodNode method = (MethodNode) methodObject;
if (names.contains(method.name)
&& method.desc.startsWith("()")) { //$NON-NLS-1$ // (): No arguments
InsnList instructions = method.instructions;
int mState = 1;
for (AbstractInsnNode curr = instructions.getFirst();
curr != null;
curr = curr.getNext()) {
switch (curr.getOpcode()) {
case -1:
// Skip label and line number nodes
continue;
case Opcodes.ALOAD:
if (mState == 1) {
fieldName = null;
mState = 2;
} else {
continue checkMethod;
}
break;
case Opcodes.GETFIELD:
if (mState == 2) {
FieldInsnNode field = (FieldInsnNode) curr;
fieldName = field.name;
mState = 3;
} else {
continue checkMethod;
}
break;
case Opcodes.ARETURN:
case Opcodes.FRETURN:
case Opcodes.IRETURN:
case Opcodes.DRETURN:
case Opcodes.LRETURN:
case Opcodes.RETURN:
if (mState == 3) {
validGetters.put(method.name, fieldName);
}
continue checkMethod;
default:
continue checkMethod;
}
}
}
}
return validGetters;
}
/**
* {@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);
}
boolean isReturnCode(final int opcode) {
return opcode == Opcodes.IRETURN || opcode == Opcodes.LRETURN || opcode == Opcodes.FRETURN || opcode == Opcodes.DRETURN || opcode == Opcodes.ARETURN || opcode == Opcodes.RETURN;
}