下面列出了org.objectweb.asm.Type#getOpcode ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void redirectStaticMethodProxytoGlobal(MethodVisitor mv, String name, String desc){
String globName = getGlobName(className);
//return new StaticMethodProxytoGlobal(mv);//+ $Globals$
mv.visitCode();
mv.visitLabel(new Label());
mv.visitMethodInsn(INVOKESTATIC, globName, "getInstance?", "()L"+globName+";", false);
int argSpace = 0;
for(Type arg : Type.getArgumentTypes(desc)){
mv.visitVarInsn(arg.getOpcode(Opcodes.ILOAD), argSpace);
argSpace += arg.getSize();
}
mv.visitMethodInsn(INVOKEVIRTUAL, globName, name, desc, false);
Type retType = Type.getReturnType(desc);
int opcode = retType.getOpcode(Opcodes.IRETURN); //Opcodes.ARETURN;
/*if(retType.getDimensions() == 1){
}*/
mv.visitInsn(opcode);
mv.visitMaxs(1, 0);
mv.visitEnd();
}
/**
* Computes the Opcode instruction for a given Type <code><code>org.objectweb.asm.Type</code>
*
* @param bi ByteInstruction class that contains the ByteCode and StackIndex
* @param t instruction for Type <code><code>org.objectweb.asm.Type</code>
*/
public static void getInstruction(final ByteInstruction bi, final Type t) {
bi.code = t.getOpcode(Opcodes.ILOAD);
bi.stackIndex = bi.nextStackIndex;
bi.nextStackIndex += t.getSize();
}
private int generateArgumentsArray(int argIndex) {
Type[] argumentTypes = Type.getArgumentTypes(methodDesc);
super.visitIntInsn(BIPUSH, argumentTypes.length);
super.visitTypeInsn(ANEWARRAY, "java/lang/Object");
for (int i = 0; i < argumentTypes.length; i++) {
Type argumentType = argumentTypes[i];
super.visitInsn(DUP);
super.visitIntInsn(BIPUSH, i);
super.visitVarInsn(argumentType.getOpcode(ILOAD), argIndex);
// boxing start
switch (argumentType.getSort()) {
case Type.BYTE:
super.visitMethodInsn(
INVOKESTATIC,
"java/lang/Byte",
"valueOf",
"(B)Ljava/lang/Byte;"
);
break;
case Type.BOOLEAN:
super.visitMethodInsn(
INVOKESTATIC,
"java/lang/Boolean",
"valueOf",
"(Z)Ljava/lang/Boolean;"
);
break;
case Type.SHORT:
super.visitMethodInsn(
INVOKESTATIC,
"java/lang/Short",
"valueOf",
"(S)Ljava/lang/Short;"
);
break;
case Type.CHAR:
super.visitMethodInsn(
INVOKESTATIC,
"java/lang/Character",
"valueOf",
"(C)Ljava/lang/Character;"
);
break;
case Type.INT:
super.visitMethodInsn(
INVOKESTATIC,
"java/lang/Integer",
"valueOf",
"(I)Ljava/lang/Integer;"
);
break;
case Type.FLOAT:
super.visitMethodInsn(
INVOKESTATIC,
"java/lang/Float",
"valueOf",
"(F)Ljava/lang/Float;"
);
break;
case Type.LONG:
super.visitMethodInsn(
INVOKESTATIC,
"java/lang/Long",
"valueOf",
"(J)Ljava/lang/Long;"
);
break;
case Type.DOUBLE:
super.visitMethodInsn(
INVOKESTATIC,
"java/lang/Double",
"valueOf",
"(D)Ljava/lang/Double;"
);
break;
}
// boxing end
super.visitInsn(AASTORE);
argIndex += argumentType.getSize();
}
super.visitVarInsn(ASTORE, argIndex);
return argIndex;
}
/**
* Returns whether a given instruction can be used to push argument of {@code type} on stack.
*/
private /* static */ boolean isPushForType(AbstractInsnNode insn, Type type) {
int opcode = insn.getOpcode();
if (opcode == type.getOpcode(Opcodes.ILOAD)) {
return true;
}
// b/62060793: AsyncAwait rewrites bytecode to convert java methods into state machine with
// support of lambdas. Constant zero values are pushed on stack for all yet uninitialized
// local variables. And SIPUSH instruction is used to advance an internal state of a state
// machine.
switch (type.getSort()) {
case Type.BOOLEAN:
return opcode == Opcodes.ICONST_0 || opcode == Opcodes.ICONST_1;
case Type.BYTE:
case Type.CHAR:
case Type.SHORT:
case Type.INT:
return opcode == Opcodes.SIPUSH
|| opcode == Opcodes.ICONST_0
|| opcode == Opcodes.ICONST_1
|| opcode == Opcodes.ICONST_2
|| opcode == Opcodes.ICONST_3
|| opcode == Opcodes.ICONST_4
|| opcode == Opcodes.ICONST_5
|| opcode == Opcodes.ICONST_M1;
case Type.LONG:
return opcode == Opcodes.LCONST_0 || opcode == Opcodes.LCONST_1;
case Type.FLOAT:
return opcode == Opcodes.FCONST_0
|| opcode == Opcodes.FCONST_1
|| opcode == Opcodes.FCONST_2;
case Type.DOUBLE:
return opcode == Opcodes.DCONST_0 || opcode == Opcodes.DCONST_1;
case Type.OBJECT:
case Type.ARRAY:
return opcode == Opcodes.ACONST_NULL;
default:
// Support for BIPUSH and LDC* opcodes is not implemented as there is no known use case.
return false;
}
}
/**
* Returns the Opcode for the specific return type
*
* @param desc method description
* @return Opcode for the specific return type
*/
public static int getReturnCode(final String desc) {
final Type t = Type.getReturnType(desc);
return t.getOpcode(Opcodes.IRETURN);
}