下面列出了org.objectweb.asm.Opcodes# JSR 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void checkOpcode(int opcode) {
if (false
// We reject JSR and RET (although these haven't been generated in a long time, anyway, and aren't allowed in new class files).
|| (Opcodes.JSR == opcode)
|| (Opcodes.RET == opcode)
// We also want to reject instructions which could interact with the thread state: MONITORENTER, MONITOREXIT.
|| (Opcodes.MONITORENTER == opcode)
|| (Opcodes.MONITOREXIT == opcode)
) {
RejectedClassException.blacklistedOpcode(opcode);
}
}
@Override
public void visitJumpInsn(int opcode, Label label) {
switch (opcode) {
case Opcodes.IFEQ:
case Opcodes.IFNE:
case Opcodes.IFLT:
case Opcodes.IFGE:
case Opcodes.IFGT:
case Opcodes.IFLE:
pop();
break;
case Opcodes.IF_ICMPEQ:
case Opcodes.IF_ICMPNE:
case Opcodes.IF_ICMPLT:
case Opcodes.IF_ICMPGE:
case Opcodes.IF_ICMPGT:
case Opcodes.IF_ICMPLE:
case Opcodes.IF_ACMPEQ:
case Opcodes.IF_ACMPNE:
pop(2);
break;
case Opcodes.GOTO:
break;
case Opcodes.JSR:
throw new RuntimeException("The JSR instruction is not supported.");
case Opcodes.IFNULL:
case Opcodes.IFNONNULL:
pop(1);
break;
default:
throw new RuntimeException("Unhandled opcode " + opcode);
}
super.visitJumpInsn(opcode, label);
}
@Override
public void visitJumpInsn(int arg0, Label arg1) {
savePreviousFrame();
switch (arg0) {
case Opcodes.IF_ACMPEQ:
case Opcodes.IF_ACMPNE:
case Opcodes.IF_ICMPEQ:
case Opcodes.IF_ICMPGE:
case Opcodes.IF_ICMPGT:
case Opcodes.IF_ICMPLE:
case Opcodes.IF_ICMPLT:
case Opcodes.IF_ICMPNE:
currentFrame.popStack();
case Opcodes.IFEQ:
case Opcodes.IFGE:
case Opcodes.IFGT:
case Opcodes.IFLE:
case Opcodes.IFLT:
case Opcodes.IFNE:
case Opcodes.IFNONNULL:
case Opcodes.IFNULL:
currentFrame.popStack();
case Opcodes.GOTO:
forwardFrames.put(arg1, new StackInfo(currentFrame));
break;
case Opcodes.JSR:
currentFrame.pushStack(retAddressType);
forwardFrames.put(arg1, new StackInfo(currentFrame));
break;
default:
logger.debug("Unhandled: ");
}
if (logger.isDebugEnabled())
logger.debug("jumpInsn " + getOpCode(arg0) + " " + arg1);
delegate.visitJumpInsn(arg0, arg1);
}
@Override
public void visitJumpInsn(final int opcode, final Label label) {
switch (opcode) {
case Opcodes.IFEQ:
ifeq(label);
break;
case Opcodes.IFNE:
ifne(label);
break;
case Opcodes.IFLT:
iflt(label);
break;
case Opcodes.IFGE:
ifge(label);
break;
case Opcodes.IFGT:
ifgt(label);
break;
case Opcodes.IFLE:
ifle(label);
break;
case Opcodes.IF_ICMPEQ:
ificmpeq(label);
break;
case Opcodes.IF_ICMPNE:
ificmpne(label);
break;
case Opcodes.IF_ICMPLT:
ificmplt(label);
break;
case Opcodes.IF_ICMPGE:
ificmpge(label);
break;
case Opcodes.IF_ICMPGT:
ificmpgt(label);
break;
case Opcodes.IF_ICMPLE:
ificmple(label);
break;
case Opcodes.IF_ACMPEQ:
ifacmpeq(label);
break;
case Opcodes.IF_ACMPNE:
ifacmpne(label);
break;
case Opcodes.GOTO:
goTo(label);
break;
case Opcodes.JSR:
jsr(label);
break;
case Opcodes.IFNULL:
ifnull(label);
break;
case Opcodes.IFNONNULL:
ifnonnull(label);
break;
default:
throw new IllegalArgumentException();
}
}
public InsnValue createConstant(AbstractInsnNode insn) throws AnalyzerException {
switch (insn.getOpcode()) {
case Opcodes.ACONST_NULL:
return InsnValue.NULL_REFERENCE_VALUE;
case Opcodes.ICONST_M1:
case Opcodes.ICONST_0:
case Opcodes.ICONST_1:
case Opcodes.ICONST_2:
case Opcodes.ICONST_3:
case Opcodes.ICONST_4:
case Opcodes.ICONST_5:
case Opcodes.BIPUSH:
case Opcodes.SIPUSH:
return InsnValue.intValue(insn);
case Opcodes.LCONST_0:
case Opcodes.LCONST_1:
return InsnValue.longValue(insn.getOpcode());
case Opcodes.FCONST_0:
case Opcodes.FCONST_1:
case Opcodes.FCONST_2:
return InsnValue.floatValue(insn.getOpcode());
case Opcodes.DCONST_0:
case Opcodes.DCONST_1:
return InsnValue.doubleValue(insn.getOpcode());
case Opcodes.LDC:
Object obj = ((LdcInsnNode) insn).cst;
if (obj instanceof Type) {
return new InsnValue((Type) obj);
} else {
Type t = Type.getType(obj.getClass());
int sort = t.getSort();
// Non-included types:
// Type.ARRAY
// Type.VOID
// Type.METHOD
switch (sort) {
case Type.BOOLEAN:
return InsnValue.intValue((int) obj);
case Type.CHAR:
return InsnValue.charValue((char) obj);
case Type.BYTE:
return InsnValue.byteValue((byte) obj);
case Type.SHORT:
return InsnValue.shortValue((short) obj);
case Type.INT:
return InsnValue.intValue((int) obj);
case Type.FLOAT:
return InsnValue.floatValue((float) obj);
case Type.LONG:
return InsnValue.longValue((long) obj);
case Type.DOUBLE:
return InsnValue.doubleValue((double) obj);
case Type.OBJECT:
return new InsnValue(t, obj);
}
return new InsnValue(t);
}
case Opcodes.NEW:
return new InsnValue(Type.getType(((TypeInsnNode) insn).desc));
case Opcodes.JSR:
// TODO: IDK if this is right.
return InsnValue.REFERENCE_VALUE;
}
return null;
}
@Override
public void visitJumpInsn(final int opcode, final Label label) {
switch (opcode) {
case Opcodes.IFEQ:
ifeq(label);
break;
case Opcodes.IFNE:
ifne(label);
break;
case Opcodes.IFLT:
iflt(label);
break;
case Opcodes.IFGE:
ifge(label);
break;
case Opcodes.IFGT:
ifgt(label);
break;
case Opcodes.IFLE:
ifle(label);
break;
case Opcodes.IF_ICMPEQ:
ificmpeq(label);
break;
case Opcodes.IF_ICMPNE:
ificmpne(label);
break;
case Opcodes.IF_ICMPLT:
ificmplt(label);
break;
case Opcodes.IF_ICMPGE:
ificmpge(label);
break;
case Opcodes.IF_ICMPGT:
ificmpgt(label);
break;
case Opcodes.IF_ICMPLE:
ificmple(label);
break;
case Opcodes.IF_ACMPEQ:
ifacmpeq(label);
break;
case Opcodes.IF_ACMPNE:
ifacmpne(label);
break;
case Opcodes.GOTO:
goTo(label);
break;
case Opcodes.JSR:
jsr(label);
break;
case Opcodes.IFNULL:
ifnull(label);
break;
case Opcodes.IFNONNULL:
ifnonnull(label);
break;
default:
throw new IllegalArgumentException();
}
}
/**
* @param opcode
* @param label
* @param s
* @return
*/
static boolean handleJVMJump ( int opcode, Label label, JVMStackState s ) {
boolean tainted;
switch ( opcode ) {
case Opcodes.IF_ICMPEQ:
case Opcodes.IF_ICMPNE:
case Opcodes.IF_ICMPLT:
case Opcodes.IF_ICMPGE:
case Opcodes.IF_ICMPGT:
case Opcodes.IF_ICMPLE:
case Opcodes.IF_ACMPEQ:
case Opcodes.IF_ACMPNE:
BaseType o1 = s.pop();
BaseType o2 = s.pop();
tainted = ! ( o1 != null ) || ! ( o2 != null ) || o1.isTainted() || o2.isTainted();
break;
case Opcodes.IFEQ:
case Opcodes.IFNE:
case Opcodes.IFLT:
case Opcodes.IFGE:
case Opcodes.IFGT:
case Opcodes.IFLE:
case Opcodes.IFNULL:
case Opcodes.IFNONNULL:
BaseType c = s.pop();
tainted = ( c == null || c.isTainted() );
break;
case Opcodes.JSR:
s.push(new BasicConstant(Type.INT_TYPE, label));
tainted = false;
break;
case Opcodes.GOTO:
tainted = false;
break;
default:
log.warn("Unsupported opcode " + opcode); //$NON-NLS-1$
tainted = true;
}
return tainted;
}
@Override
public void visitJumpInsn(final int opcode, final Label label) {
switch (opcode) {
case Opcodes.IFEQ:
ifeq(label);
break;
case Opcodes.IFNE:
ifne(label);
break;
case Opcodes.IFLT:
iflt(label);
break;
case Opcodes.IFGE:
ifge(label);
break;
case Opcodes.IFGT:
ifgt(label);
break;
case Opcodes.IFLE:
ifle(label);
break;
case Opcodes.IF_ICMPEQ:
ificmpeq(label);
break;
case Opcodes.IF_ICMPNE:
ificmpne(label);
break;
case Opcodes.IF_ICMPLT:
ificmplt(label);
break;
case Opcodes.IF_ICMPGE:
ificmpge(label);
break;
case Opcodes.IF_ICMPGT:
ificmpgt(label);
break;
case Opcodes.IF_ICMPLE:
ificmple(label);
break;
case Opcodes.IF_ACMPEQ:
ifacmpeq(label);
break;
case Opcodes.IF_ACMPNE:
ifacmpne(label);
break;
case Opcodes.GOTO:
goTo(label);
break;
case Opcodes.JSR:
jsr(label);
break;
case Opcodes.IFNULL:
ifnull(label);
break;
case Opcodes.IFNONNULL:
ifnonnull(label);
break;
default:
throw new IllegalArgumentException();
}
}
@Override
public void visitJumpInsn(final int opcode, final Label label) {
switch (opcode) {
case Opcodes.IFEQ:
ifeq(label);
break;
case Opcodes.IFNE:
ifne(label);
break;
case Opcodes.IFLT:
iflt(label);
break;
case Opcodes.IFGE:
ifge(label);
break;
case Opcodes.IFGT:
ifgt(label);
break;
case Opcodes.IFLE:
ifle(label);
break;
case Opcodes.IF_ICMPEQ:
ificmpeq(label);
break;
case Opcodes.IF_ICMPNE:
ificmpne(label);
break;
case Opcodes.IF_ICMPLT:
ificmplt(label);
break;
case Opcodes.IF_ICMPGE:
ificmpge(label);
break;
case Opcodes.IF_ICMPGT:
ificmpgt(label);
break;
case Opcodes.IF_ICMPLE:
ificmple(label);
break;
case Opcodes.IF_ACMPEQ:
ifacmpeq(label);
break;
case Opcodes.IF_ACMPNE:
ifacmpne(label);
break;
case Opcodes.GOTO:
goTo(label);
break;
case Opcodes.JSR:
jsr(label);
break;
case Opcodes.IFNULL:
ifnull(label);
break;
case Opcodes.IFNONNULL:
ifnonnull(label);
break;
default:
throw new IllegalArgumentException();
}
}
@Override
public void appendInstruction(StringBuilder b, List<Instruction> instructions) {
b.append(" ");
switch(opcode) {
case Opcodes.IFEQ:
b.append("if(POP_INT() == 0) /* IFEQ */ ");
break;
case Opcodes.IFNE:
b.append("if(POP_INT() != 0) /* IFNE */ ");
break;
case Opcodes.IFLT:
b.append("if(POP_INT() < 0) /* IFLT */ ");
break;
case Opcodes.IFGE:
b.append("if(POP_INT() >= 0) /* IFGE */ ");
break;
case Opcodes.IFGT:
b.append("if(POP_INT() > 0) /* IFGT */ ");
break;
case Opcodes.IFLE:
b.append("if(POP_INT() <= 0) /* IFLE */ ");
break;
case Opcodes.IF_ICMPEQ:
b.append("SP-=2; if((*SP).data.i == SP[1].data.i) /* IF_ICMPEQ */ ");
break;
case Opcodes.IF_ICMPNE:
b.append("SP-=2; if((*SP).data.i != SP[1].data.i) /* IF_ICMPNE */ ");
break;
case Opcodes.IF_ICMPLT:
b.append("SP-=2; if((*SP).data.i < SP[1].data.i) /* IF_ICMPLT */ ");
break;
case Opcodes.IF_ICMPGE:
b.append("SP-=2; if((*SP).data.i >= SP[1].data.i) /* IF_ICMPGE */ ");
break;
case Opcodes.IF_ICMPGT:
b.append("SP-=2; if((*SP).data.i > SP[1].data.i) /* IF_ICMPGT */ ");
break;
case Opcodes.IF_ICMPLE:
b.append("SP-=2; if((*SP).data.i <= SP[1].data.i) /* IF_ICMPLE */ ");
break;
case Opcodes.IF_ACMPEQ:
b.append("SP-=2; if((*SP).data.o == SP[1].data.o) /* IF_ACMPEQ */ ");
break;
case Opcodes.IF_ACMPNE:
b.append("SP-=2; if((*SP).data.o != SP[1].data.o) /* IF_ACMPNE */ ");
break;
case Opcodes.GOTO:
// this space intentionally left blank
break;
case Opcodes.JSR:
b.append("/* JSR TODO */");
/*b.append("PUSH_")
b.append("goto label_");
b.append(label.toString());
b.append(";\n");
b.append("JSR_RETURN_LABEL_");
b.append(jsrCounter);
b.append(":");
jsrCounter++;*/
return;
case Opcodes.IFNULL:
b.append("if(POP_OBJ() == JAVA_NULL) /* IFNULL */ ");
break;
case Opcodes.IFNONNULL:
b.append("if(POP_OBJ() != JAVA_NULL) /* IFNONNULL */ ");
break;
}
if(TryCatch.isTryCatchInMethod()) {
b.append("JUMP_TO(label_");
b.append(label.toString());
b.append(", ");
b.append(LabelInstruction.getLabelCatchDepth(label, instructions));
b.append(");\n");
} else {
b.append("goto label_");
b.append(label.toString());
b.append(";\n");
}
}
public static Match<AbstractInsnNode> aConditionalJump() {
return (c, t) -> (t instanceof JumpInsnNode)
&& (t.getOpcode() != Opcodes.GOTO)
&& (t.getOpcode() != Opcodes.JSR);
}