List of usage examples for org.objectweb.asm Opcodes IF_ACMPEQ
int IF_ACMPEQ
To view the source code for org.objectweb.asm Opcodes IF_ACMPEQ.
Click Source Link
From source file:org.jacoco.core.internal.analysis.filter.TryWithResourcesEcjFilterTest.java
License:Open Source License
/** * ECJ for//w w w. j av a2s.c o m * * <pre> * try (r0 = ...; r1 = ...; r2= ...) { * ... * } finally (...) { * ... * } * ... * </pre> * * generates * * <pre> * ACONST_NULL * ASTORE primaryExc * ACONST_NULL * ASTORE suppressedExc * ... * ASTORE r1 * ... * ASTORE r2 * ... * ASTORE r3 * * ... // body * * ALOAD r3 * IFNULL r2_close * ALOAD r3 * INVOKEVIRTUAL close:()V * GOTO r2_close * * ASTORE primaryExc * ALOAD r3 * IFNULL n * ALOAD r3 * INVOKEVIRTUAL close:()V * n: * ALOAD primaryExc * ATHROW * * r2_close: * ALOAD r2 * IFNULL r1_close * ALOAD r2 * INVOKEVIRTUAL close:()V * GOTO r1_close * * ASTORE suppressedExc * ALOAD primaryExc * IFNONNULL s * ALOAD suppressedExc * ASTORE primaryExc * GOTO e * s: * ALOAD primaryExc * ALOAD suppressedExc * IF_ACMPEQ e * ALOAD primaryExc * ALOAD suppressedExc * INVOKEVIRTUAL java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V * e: * * ALOAD r2 * IFNULL n * ALOAD r2 * INVOKEVIRTUAL close:()V * n: * ALOAD primaryExc * ATHROW * * r1_close: * ALOAD r1 * IFNULL after * ALOAD r1 * INVOKEVIRTUAL close:()V * GOTO after * * ASTORE suppressedExc * ALOAD primaryExc * IFNONNULL s * ALOAD suppressedExc * ASTORE primaryExc * GOTO e * s: * ALOAD primaryExc * ALOAD suppressedExc * IF_ACMPEQ e * ALOAD primaryExc * ALOAD suppressedExc * INVOKEVIRTUAL java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V * e: * * ALOAD r1 * IFNULL n * ALOAD r1 * INVOKEVIRTUAL close:()V * n: * ALOAD primaryExc * ATHROW * * ASTORE suppressedExc * ALOAD primaryExc * IFNONNULL s * ALOAD suppressedExc * ASTORE primaryExc * GOTO e * s: * ALOAD primaryExc * ALOAD suppressedExc * IF_ACMPEQ e * ALOAD primaryExc * ALOAD suppressedExc * INVOKEVIRTUAL java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V * e: * * ALOAD primaryExc * ATHROW * * ... // additional handlers for catch blocks and finally on exceptional path * * after: * ... // finally on normal path * ... * </pre> */ @Test public void ecj() { final Range range0 = new Range(); final Range range1 = new Range(); final Label handler = new Label(); m.visitTryCatchBlock(handler, handler, handler, null); // primaryExc = null m.visitInsn(Opcodes.ACONST_NULL); m.visitVarInsn(Opcodes.ASTORE, 1); // suppressedExc = null m.visitInsn(Opcodes.ACONST_NULL); m.visitVarInsn(Opcodes.ASTORE, 2); // body m.visitInsn(Opcodes.NOP); final Label l4 = new Label(); final Label l7 = new Label(); final Label end = new Label(); { // nextIsEcjClose("r0") m.visitVarInsn(Opcodes.ALOAD, 5); range0.fromInclusive = m.instructions.getLast(); m.visitJumpInsn(Opcodes.IFNULL, l4); m.visitVarInsn(Opcodes.ALOAD, 5); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun2$Resource", "close", "()V", false); } m.visitJumpInsn(Opcodes.GOTO, l4); range0.toInclusive = m.instructions.getLast(); // catch (any primaryExc) m.visitLabel(handler); range1.fromInclusive = m.instructions.getLast(); m.visitVarInsn(Opcodes.ASTORE, 1); { // nextIsEcjCloseAndThrow("r0") m.visitVarInsn(Opcodes.ALOAD, 5); Label l11 = new Label(); m.visitJumpInsn(Opcodes.IFNULL, l11); m.visitVarInsn(Opcodes.ALOAD, 5); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun2$Resource", "close", "()V", false); m.visitLabel(l11); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); } m.visitLabel(l4); { // nextIsEcjClose("r1") m.visitVarInsn(Opcodes.ALOAD, 4); m.visitJumpInsn(Opcodes.IFNULL, l7); m.visitVarInsn(Opcodes.ALOAD, 4); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun2$Resource", "close", "()V", false); } m.visitJumpInsn(Opcodes.GOTO, l7); { // nextIsEcjSuppress m.visitVarInsn(Opcodes.ASTORE, 2); m.visitVarInsn(Opcodes.ALOAD, 1); final Label suppressStart = new Label(); m.visitJumpInsn(Opcodes.IFNONNULL, suppressStart); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitVarInsn(Opcodes.ASTORE, 1); final Label suppressEnd = new Label(); m.visitJumpInsn(Opcodes.GOTO, suppressEnd); m.visitLabel(suppressStart); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitJumpInsn(Opcodes.IF_ACMPEQ, suppressEnd); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false); m.visitLabel(suppressEnd); } { // nextIsEcjCloseAndThrow("r1") m.visitVarInsn(Opcodes.ALOAD, 4); final Label l14 = new Label(); m.visitJumpInsn(Opcodes.IFNULL, l14); m.visitVarInsn(Opcodes.ALOAD, 4); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun2$Resource", "close", "()V", false); m.visitLabel(l14); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); } m.visitLabel(l7); { // nextIsEcjClose("r2") m.visitVarInsn(Opcodes.ALOAD, 3); m.visitJumpInsn(Opcodes.IFNULL, end); m.visitVarInsn(Opcodes.ALOAD, 3); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun2$Resource", "close", "()V", false); m.visitJumpInsn(Opcodes.GOTO, end); } { // nextIsEcjSuppress m.visitVarInsn(Opcodes.ASTORE, 2); m.visitVarInsn(Opcodes.ALOAD, 1); final Label suppressStart = new Label(); m.visitJumpInsn(Opcodes.IFNONNULL, suppressStart); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitVarInsn(Opcodes.ASTORE, 1); final Label suppressEnd = new Label(); m.visitJumpInsn(Opcodes.GOTO, suppressEnd); m.visitLabel(suppressStart); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitJumpInsn(Opcodes.IF_ACMPEQ, suppressEnd); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false); m.visitLabel(suppressEnd); } { // nextIsEcjCloseAndThrow("r2") m.visitVarInsn(Opcodes.ALOAD, 3); final Label l18 = new Label(); m.visitJumpInsn(Opcodes.IFNULL, l18); m.visitVarInsn(Opcodes.ALOAD, 3); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun2$Resource", "close", "()V", false); m.visitLabel(l18); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); } { // nextIsEcjSuppress m.visitVarInsn(Opcodes.ASTORE, 2); m.visitVarInsn(Opcodes.ALOAD, 1); final Label suppressStart = new Label(); m.visitJumpInsn(Opcodes.IFNONNULL, suppressStart); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitVarInsn(Opcodes.ASTORE, 1); final Label suppressEnd = new Label(); m.visitJumpInsn(Opcodes.GOTO, suppressEnd); m.visitLabel(suppressStart); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitJumpInsn(Opcodes.IF_ACMPEQ, suppressEnd); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false); m.visitLabel(suppressEnd); } // throw primaryExc m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); range1.toInclusive = m.instructions.getLast(); // additional handlers m.visitInsn(Opcodes.NOP); filter.filter(m, context, output); assertIgnored(range0, range1); }
From source file:org.jacoco.core.internal.analysis.filter.TryWithResourcesEcjFilterTest.java
License:Open Source License
/** * ECJ for//from w w w .j av a2s . c o m * * <pre> * try (r1 = ...; r2 = ...; r3 = ...) { * return ... * } finally { * ... * } * </pre> * * generates * * <pre> * ACONST_NULL * astore primaryExc * ACONST_NULL * astore suppressedExc * * ... * ASTORE r1 * ... * ASTORE r2 * ... * ASTORE r3 * * ... // body * * ALOAD r3 * IFNULL n * ALOAD r3 * INVOKEVIRTUAL close:()V * n: * ALOAD r2 * IFNULL n * ALOAD r2 * INVOKEVIRTUAL close:()V * n: * ALOAD r1 * IFNULL n * ALOAD r1 * INVOKEVIRTUAL close:()V * n: * * ... // finally on normal path * ARETURN * * ASTORE primaryExc * ALOAD r3 * IFNULL n * ALOAD r3 * INVOKEVIRTUAL close:()V * n: * ALOAD primaryExc * ATHROW * * ASTORE suppressedExc * ALOAD primaryExc * IFNONNULL s * ALOAD suppressedExc * ASTORE primaryExc * GOTO e * s: * ALOAD primaryExc * ALOAD suppressedExc * IF_ACMPEQ e * ALOAD primaryExc * ALOAD suppressedExc * INVOKEVIRTUAL java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V * e: * * ALOAD r2 * IFNULL n * ALOAD r2 * INVOKEVIRTUAL close:()V * n: * ALOAD primaryExc * ATHROW * * ASTORE suppressedExc * ALOAD primaryExc * IFNONNULL s * ALOAD suppressedExc * ASTORE primaryExc * GOTO e * s: * ALOAD primaryExc * ALOAD suppressedExc * IF_ACMPEQ e * ALOAD primaryExc * ALOAD suppressedExc * INVOKEVIRTUAL java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V * e: * * ALOAD r1 * IFNULL n * ALOAD r1 * INVOKEVIRTUAL close:()V * n: * ALOAD primaryExc * ATHROW * * ASTORE suppressedExc * ALOAD primaryExc * IFNONNULL s * ALOAD suppressedExc * ASTORE primaryExc * GOTO e * s: * ALOAD primaryExc * ALOAD suppressedExc * IF_ACMPEQ e * ALOAD primaryExc * ALOAD suppressedExc * INVOKEVIRTUAL java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V * e: * * ALOAD primaryExc * ATHROW * * ... // additional handlers for catch blocks and finally on exceptional path * </pre> */ @Test public void ecj_noFlowOut() { final Range range0 = new Range(); final Range range1 = new Range(); final Label handler = new Label(); m.visitTryCatchBlock(handler, handler, handler, null); // primaryExc = null m.visitInsn(Opcodes.ACONST_NULL); m.visitVarInsn(Opcodes.ASTORE, 1); // suppressedExc = null m.visitInsn(Opcodes.ACONST_NULL); m.visitVarInsn(Opcodes.ASTORE, 2); // body m.visitInsn(Opcodes.NOP); { // nextIsEcjClose("r0") final Label label = new Label(); m.visitVarInsn(Opcodes.ALOAD, 5); range0.fromInclusive = m.instructions.getLast(); m.visitJumpInsn(Opcodes.IFNULL, label); m.visitVarInsn(Opcodes.ALOAD, 5); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); m.visitLabel(label); } { // nextIsEcjClose("r1") final Label label = new Label(); m.visitVarInsn(Opcodes.ALOAD, 4); m.visitJumpInsn(Opcodes.IFNULL, label); m.visitVarInsn(Opcodes.ALOAD, 4); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); m.visitLabel(label); } { // nextIsEcjClose("r2") final Label label = new Label(); m.visitVarInsn(Opcodes.ALOAD, 3); m.visitJumpInsn(Opcodes.IFNULL, label); m.visitVarInsn(Opcodes.ALOAD, 3); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); range0.toInclusive = m.instructions.getLast(); m.visitLabel(label); } // finally m.visitInsn(Opcodes.NOP); m.visitInsn(Opcodes.ARETURN); // catch (any primaryExc) m.visitLabel(handler); range1.fromInclusive = m.instructions.getLast(); m.visitVarInsn(Opcodes.ASTORE, 1); { // nextIsEcjCloseAndThrow("r0") m.visitVarInsn(Opcodes.ALOAD, 5); final Label throwLabel = new Label(); m.visitJumpInsn(Opcodes.IFNULL, throwLabel); m.visitVarInsn(Opcodes.ALOAD, 5); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); m.visitLabel(throwLabel); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); } { // nextIsEcjSuppress m.visitVarInsn(Opcodes.ASTORE, 2); m.visitVarInsn(Opcodes.ALOAD, 1); final Label suppressStart = new Label(); m.visitJumpInsn(Opcodes.IFNONNULL, suppressStart); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitVarInsn(Opcodes.ASTORE, 1); final Label suppressEnd = new Label(); m.visitJumpInsn(Opcodes.GOTO, suppressEnd); m.visitLabel(suppressStart); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitJumpInsn(Opcodes.IF_ACMPEQ, suppressEnd); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false); m.visitLabel(suppressEnd); } { // nextIsEcjCloseAndThrow("r1") m.visitVarInsn(Opcodes.ALOAD, 4); final Label throwLabel = new Label(); m.visitJumpInsn(Opcodes.IFNULL, throwLabel); m.visitVarInsn(Opcodes.ALOAD, 4); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); m.visitLabel(throwLabel); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); } { // nextIsEcjSuppress m.visitVarInsn(Opcodes.ASTORE, 2); m.visitVarInsn(Opcodes.ALOAD, 1); final Label suppressStart = new Label(); m.visitJumpInsn(Opcodes.IFNONNULL, suppressStart); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitVarInsn(Opcodes.ASTORE, 1); final Label suppressEnd = new Label(); m.visitJumpInsn(Opcodes.GOTO, suppressEnd); m.visitLabel(suppressStart); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitJumpInsn(Opcodes.IF_ACMPEQ, suppressEnd); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false); m.visitLabel(suppressEnd); } { // nextIsEcjCloseAndThrow("r2") m.visitVarInsn(Opcodes.ALOAD, 3); final Label throwLabel = new Label(); m.visitJumpInsn(Opcodes.IFNULL, throwLabel); m.visitVarInsn(Opcodes.ALOAD, 3); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); m.visitLabel(throwLabel); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); } { // nextIsEcjSuppress m.visitVarInsn(Opcodes.ASTORE, 2); m.visitVarInsn(Opcodes.ALOAD, 1); final Label suppressStart = new Label(); m.visitJumpInsn(Opcodes.IFNONNULL, suppressStart); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitVarInsn(Opcodes.ASTORE, 1); final Label suppressEnd = new Label(); m.visitJumpInsn(Opcodes.GOTO, suppressEnd); m.visitLabel(suppressStart); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitJumpInsn(Opcodes.IF_ACMPEQ, suppressEnd); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false); m.visitLabel(suppressEnd); } // throw primaryExc m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); range1.toInclusive = m.instructions.getLast(); // additional handlers m.visitInsn(Opcodes.NOP); filter.filter(m, context, output); assertIgnored(range0, range1); }
From source file:org.jacoco.core.internal.instr.FrameTracker.java
License:Open Source License
@Override public void visitJumpInsn(final int opcode, final Label label) { switch (opcode) { case Opcodes.GOTO: break;/* w ww . j ava 2 s.com*/ case Opcodes.IFEQ: case Opcodes.IFNE: case Opcodes.IFLT: case Opcodes.IFGE: case Opcodes.IFGT: case Opcodes.IFLE: case Opcodes.IFNULL: case Opcodes.IFNONNULL: pop(1); 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; default: throw new IllegalArgumentException(); } mv.visitJumpInsn(opcode, label); }
From source file:org.jacoco.core.internal.instr.MethodInstrumenter.java
License:Open Source License
private int getInverted(final int opcode) { switch (opcode) { case Opcodes.IFEQ: return Opcodes.IFNE; case Opcodes.IFNE: return Opcodes.IFEQ; case Opcodes.IFLT: return Opcodes.IFGE; case Opcodes.IFGE: return Opcodes.IFLT; case Opcodes.IFGT: return Opcodes.IFLE; case Opcodes.IFLE: return Opcodes.IFGT; case Opcodes.IF_ICMPEQ: return Opcodes.IF_ICMPNE; case Opcodes.IF_ICMPNE: return Opcodes.IF_ICMPEQ; case Opcodes.IF_ICMPLT: return Opcodes.IF_ICMPGE; case Opcodes.IF_ICMPGE: return Opcodes.IF_ICMPLT; case Opcodes.IF_ICMPGT: return Opcodes.IF_ICMPLE; case Opcodes.IF_ICMPLE: return Opcodes.IF_ICMPGT; case Opcodes.IF_ACMPEQ: return Opcodes.IF_ACMPNE; case Opcodes.IF_ACMPNE: return Opcodes.IF_ACMPEQ; case Opcodes.IFNULL: return Opcodes.IFNONNULL; case Opcodes.IFNONNULL: return Opcodes.IFNULL; }/* w ww . ja v a 2 s .c o m*/ throw new IllegalArgumentException(); }
From source file:org.jacoco.core.internal.instr.MethodInstrumenterTest.java
License:Open Source License
@Test public void testVisitJumpInsnWithProbe_IF_ACMPEQ() { testVisitJumpInsnWithProbe(Opcodes.IF_ACMPEQ, Opcodes.IF_ACMPNE); }
From source file:org.jacoco.core.internal.instr.MethodInstrumenterTest.java
License:Open Source License
@Test public void testVisitJumpInsnWithProbe_IF_ACMPNE() { testVisitJumpInsnWithProbe(Opcodes.IF_ACMPNE, Opcodes.IF_ACMPEQ); }
From source file:org.jboss.byteman.agent.adapter.cfg.BBlock.java
License:Open Source License
/** * write a string represenattion of this block to the buffer * @param buf the buffer to be written to * @return/* www .jav a 2 s. com*/ */ void printTo(StringBuffer buf) { int blockIdx = this.getBlockIdx(); buf.append(this.getLabel().getOffset()); buf.append(": BB "); buf.append(blockIdx); buf.append("\n"); FanOut containsFanOut = cfg.getContains(this); Iterator<Label> containsIter; Label containedLabel; int containedPosition; if (containsFanOut != null) { containsIter = containsFanOut.iterator(); if (containsIter.hasNext()) { containedLabel = containsIter.next(); containedPosition = cfg.getBlockInstructionIdx(containedLabel); } else { containedLabel = null; containedPosition = -1; } } else { containsIter = null; containedLabel = null; containedPosition = -1; } int instructionCount = this.getInstructionCount(); for (int i = 0; i < instructionCount; i++) { // we will never enter this if containedPosition is -1 which safeguards us when containsIter // is null or containedLabel is null while (containedPosition == i) { buf.append(containedLabel.getOffset()); buf.append(": "); buf.append(containedLabel); buf.append(" +"); buf.append(containedPosition); if (cfg.tryCatchStart(containedLabel)) { List<TryCatchDetails> detailsList = cfg.tryCatchStartDetails(containedLabel); int detailsCount = detailsList.size(); for (int j = 0; j < detailsCount; j++) { TryCatchDetails details = detailsList.get(j); Label handlerLabel = details.getHandler(); CodeLocation handlerLocation = cfg.getLocation(handlerLabel); buf.append(" try "); buf.append(details.getType()); buf.append(" "); if (handlerLocation != null) { buf.append(handlerLabel.getOffset()); } else { buf.append("??"); } buf.append(" "); buf.append(handlerLabel); } } if (cfg.tryCatchEnd(containedLabel)) { List<TryCatchDetails> detailsList = cfg.tryCatchEndDetails(containedLabel); int detailsCount = detailsList.size(); for (int j = 0; j < detailsCount; j++) { TryCatchDetails details = detailsList.get(j); Label handlerLabel = details.getHandler(); CodeLocation handlerLocation = cfg.getLocation(handlerLabel); buf.append(" catch "); buf.append(details.getType()); buf.append(" "); if (handlerLocation != null) { buf.append(handlerLabel.getOffset()); } else { buf.append("??"); } buf.append(" "); buf.append(handlerLabel); } } if (cfg.tryCatchHandlerStart(containedLabel)) { List<TryCatchDetails> detailsList = cfg.tryCatchHandlerStartDetails(containedLabel); int detailsCount = detailsList.size(); for (int j = 0; j < detailsCount; j++) { TryCatchDetails details = detailsList.get(j); buf.append(" handle "); buf.append(details.getType()); buf.append(" "); buf.append(details.getStart().getOffset()); buf.append(" "); buf.append(details.getEnd().getOffset()); } } if (cfg.triggerStart(containedLabel)) { buf.append(" trigger start"); TriggerDetails details = cfg.triggerStartDetails(containedLabel); } if (cfg.triggerEnd(containedLabel)) { buf.append(" trigger end"); } buf.append("\n"); List<CodeLocation> openEnters = cfg.getOpenMonitorEnters(containedLabel); if (openEnters != null) { int openCount = openEnters.size(); if (openCount > 0) { buf.append("open monitors: "); for (int j = 0; j < openCount; j++) { CodeLocation l = openEnters.get(j); buf.append(" BB"); buf.append(l.getBlock().getBlockIdx()); buf.append("."); buf.append(l.getInstructionIdx()); } buf.append('\n'); } } containedLabel = (containsIter.hasNext() ? containsIter.next() : null); containedPosition = (containedLabel != null ? cfg.getBlockInstructionIdx(containedLabel) : -1); } // buf.append(" "); buf.append(blockIdx); buf.append("."); buf.append(i); buf.append(": "); int opcode = this.getInstruction(i); switch (OpcodesHelper.insnType(opcode)) { case OpcodesHelper.INSN_NONE: { // print the instruction name buf.append(OpcodesHelper.insnName(opcode)); if (opcode == Opcodes.MONITOREXIT) { CodeLocation exit = new CodeLocation(this, i); CodeLocation enter = cfg.getPairedEnter(exit); // print the corresponding open instruction buf.append(" (enter: "); buf.append(enter); buf.append(")"); } buf.append("\n"); } break; case OpcodesHelper.INSN_INT: { // just print the instruction name and one integer argument int intValue = this.getInstructionArg(i, 0); buf.append(OpcodesHelper.insnName(opcode)); buf.append(" "); buf.append(intValue); buf.append("\n"); } break; case OpcodesHelper.INSN_LDC: { // print the instruction and one constant argument int nameIdx = this.getInstructionArg(i, 0); String name = cfg.getName(nameIdx); buf.append(OpcodesHelper.insnName(opcode)); buf.append(" "); buf.append(name); buf.append("\n"); } break; case OpcodesHelper.INSN_VAR: { // print the instruction and the var idx int varIdx = this.getInstructionArg(i, 0); buf.append(OpcodesHelper.insnName(opcode)); buf.append(" "); buf.append(varIdx); buf.append("\n"); } break; case OpcodesHelper.INSN_IINC: { // print the instruction and the var idx int increment = this.getInstructionArg(i, 0); buf.append(OpcodesHelper.insnName(opcode)); buf.append(" "); buf.append(increment); buf.append("\n"); } break; case OpcodesHelper.INSN_JUMP: { // note that we may not have generated the code for the jump target yet Label targetLabel = this.firstOut(); CodeLocation targetLocation = cfg.getLocation(targetLabel); int targetPos = (targetLocation != null ? targetLabel.getOffset() : -1); switch (opcode) { case Opcodes.IFEQ: buf.append("IFEQ "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IFNE: buf.append("IFNE "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IFLT: buf.append("IFLT "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IFGE: buf.append("IFGE "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IFGT: buf.append("IFGT "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IFLE: buf.append("IFLE "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IF_ICMPEQ: buf.append("IF_ICMPEQ "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IF_ICMPNE: buf.append("IF_ICMPNE "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IF_ICMPLT: buf.append("IF_ICMPLT "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IF_ICMPGE: buf.append("IF_ICMPGE "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IF_ICMPGT: buf.append("IF_ICMPGT "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IF_ICMPLE: buf.append("IF_ICMPLE "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IF_ACMPEQ: buf.append("IF_ACMPEQ "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IF_ACMPNE: buf.append("IF_ACMPNE "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.GOTO: buf.append("GOTO "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.JSR: buf.append("JSR "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IFNULL: buf.append("IFNULL "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; case Opcodes.IFNONNULL: buf.append("IFNONNULL "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } buf.append("\n"); break; } } break; case OpcodesHelper.INSN_TSWITCH: { Label targetLabel; CodeLocation targetLocation; int targetPos; // print the instruction followed by the jump table discriminant min and max and then // the jump labels int min = this.getInstructionArg(i, 0); int max = this.getInstructionArg(i, 1); int count = (max + 1 - min); buf.append(OpcodesHelper.insnName(opcode)); buf.append(" "); buf.append(min); buf.append(" "); buf.append(max); buf.append("\n"); for (int j = 1; j <= count; j++) { // note that we may not have generated the code for the jump target yet targetLabel = this.nthOut(j); targetLocation = cfg.getLocation(targetLabel); targetPos = (targetLocation != null ? targetLabel.getOffset() : -1); buf.append(" "); buf.append(min + j); buf.append(" : "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } } targetLabel = this.firstOut(); targetLocation = cfg.getLocation(targetLabel); targetPos = (targetLocation != null ? targetLabel.getOffset() : -1); buf.append(" dflt : "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } } break; case OpcodesHelper.INSN_LOOKUP: { Label targetLabel; CodeLocation targetLocation; int targetPos; // print the instruction followed by each jump table discriminant and label int count = this.getInstructionArg(i, 0); buf.append(OpcodesHelper.insnName(opcode)); buf.append("\n"); for (int j = 1; j <= count; j++) { // note that we may not have generated the code for the jump target yet targetLabel = this.nthOut(j); targetLocation = cfg.getLocation(targetLabel); targetPos = (targetLocation != null ? targetLabel.getOffset() : -1); buf.append(" "); buf.append(this.getInstructionArg(i, j)); buf.append(" : "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } } targetLabel = this.firstOut(); targetLocation = cfg.getLocation(targetLabel); targetPos = (targetLocation != null ? targetLabel.getOffset() : -1); buf.append(" dflt : "); if (targetPos >= 0) { buf.append(targetPos); buf.append(" BB "); buf.append(targetLocation.getBlock().getBlockIdx()); buf.append(" "); buf.append(targetLabel); } else { buf.append("?? "); buf.append(targetLabel); } } break; case OpcodesHelper.INSN_FIELD: case OpcodesHelper.INSN_METHOD: { // print the instruction with the owner, name and descriptor int idx1 = this.getInstructionArg(i, 0); int idx2 = this.getInstructionArg(i, 1); int idx3 = this.getInstructionArg(i, 2); String owner = cfg.getName(idx1); String name = cfg.getName(idx2); String desc = cfg.getName(idx3); buf.append(OpcodesHelper.insnName(opcode)); buf.append(" "); buf.append(owner); buf.append(" "); buf.append(name); buf.append(" "); buf.append(desc); buf.append("\n"); } break; case OpcodesHelper.INSN_TYPE: { // print the instruction with the type name int idx = this.getInstructionArg(i, 0); String name = cfg.getName(idx); buf.append(OpcodesHelper.insnName(opcode)); buf.append(" "); buf.append(name); buf.append("\n"); } break; case OpcodesHelper.INSN_MULTIANEWARRAY: { // print the instruction with the typename and the dimension count int idx = this.getInstructionArg(i, 0); int dims = this.getInstructionArg(i, 1); String name = cfg.getName(idx); buf.append(OpcodesHelper.insnName(opcode)); buf.append(" "); buf.append(name); buf.append(" "); buf.append(dims); buf.append("\n"); } break; case OpcodesHelper.INSN_UNUSED: { // print the instruction buf.append(OpcodesHelper.insnName(opcode)); buf.append("!!!\n"); } break; } } // print the active starts for this block if (activeTryStarts != null) { Iterator<TryCatchDetails> activeStartsIter = activeTryStarts.iterator(); while (activeStartsIter.hasNext()) { TryCatchDetails details = activeStartsIter.next(); Label label = details.getStart(); BBlock block = cfg.getBlock(label); buf.append("try: "); if (block != null) { buf.append(label.getOffset()); buf.append(" "); buf.append(block.getBlockIdx()); buf.append("."); buf.append(cfg.getBlockInstructionIdx(label)); } else { buf.append(label); } buf.append(" catch: "); label = details.getEnd(); block = cfg.getBlock(label); if (block != null) { buf.append(label.getOffset()); buf.append(" "); buf.append(block.getBlockIdx()); buf.append("."); buf.append(cfg.getBlockInstructionIdx(label)); } else { buf.append(label); } buf.append(" handle: "); label = details.getHandler(); block = cfg.getBlock(label); if (block != null) { buf.append(label.getOffset()); buf.append(" "); buf.append(block.getBlockIdx()); buf.append("."); buf.append(cfg.getBlockInstructionIdx(label)); } else { buf.append(label); } buf.append(" "); buf.append(details.getType()); buf.append("\n"); } } }
From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java
License:Open Source License
/** * Generates the instructions to jump to a label based on the comparison of * the top two stack values.//from w w w. ja v a 2 s . c o m * * @param type the type of the top two stack values. * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT, * LE. * @param label where to jump if the comparison result is <tt>true</tt>. */ public void ifCmp(final Type type, final int mode, final Label label) { int intOp = -1; switch (type.getSort()) { case Type.LONG: visitInsn(Opcodes.LCMP); break; case Type.DOUBLE: visitInsn(Opcodes.DCMPG); break; case Type.FLOAT: visitInsn(Opcodes.FCMPG); break; case Type.ARRAY: case Type.OBJECT: switch (mode) { case EQ: visitJumpInsn(Opcodes.IF_ACMPEQ, label); return; case NE: visitJumpInsn(Opcodes.IF_ACMPNE, label); return; } throw new IllegalArgumentException("Bad comparison for type " + type); default: switch (mode) { case EQ: intOp = Opcodes.IF_ICMPEQ; break; case NE: intOp = Opcodes.IF_ICMPNE; break; case GE: intOp = Opcodes.IF_ICMPGE; break; case LT: intOp = Opcodes.IF_ICMPLT; break; case LE: intOp = Opcodes.IF_ICMPLE; break; case GT: intOp = Opcodes.IF_ICMPGT; break; } visitJumpInsn(intOp, label); return; } int jumpMode = mode; switch (mode) { case GE: jumpMode = LT; break; case LE: jumpMode = GT; break; } visitJumpInsn(jumpMode, label); }
From source file:org.jboss.byteman.agent.adapter.RuleTriggerMethodAdapter.java
License:Open Source License
@Override public void visitJumpInsn(int opcode, Label label) { super.visitJumpInsn(opcode, label); switch (opcode) { case Opcodes.IFEQ: case Opcodes.IFNE: case Opcodes.IFLT: case Opcodes.IFGE: case Opcodes.IFGT: case Opcodes.IFLE: 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: { // create a new current block and add the label supplied in the call as the // first out of the old current block and the label of the new current block as // the second out cfg.add(opcode);//from w ww.j a v a 2s .c o m Label newStart = super.newLabel(); // must call split before visiting the label cfg.split(newStart, label, newStart); visitLabel(newStart); } break; case Opcodes.GOTO: { // create a new current block and add the label supplied in the call as the // first out of the old current block cfg.add(opcode); Label newStart = super.newLabel(); // must call split before visiting the label cfg.split(newStart, label); visitLabel(newStart); } break; case Opcodes.JSR: { // create a new current block and add the label supplied in the call as the first out // of the current block -- the new current block is a potential return point from the // JSR but we cannot represent that statically cfg.add(opcode); Label newStart = super.newLabel(); // must call split before visiting the label cfg.split(newStart, label, newStart); visitLabel(newStart); } break; case Opcodes.IFNULL: case Opcodes.IFNONNULL: { // create a new current block and add the label supplied in the call as the // first out of the old current block and the label of the new current block as // the second out cfg.add(opcode); Label newStart = super.newLabel(); // must call split before visiting the label cfg.split(newStart, label, newStart); visitLabel(newStart); } break; } }
From source file:org.jboss.byteman.rule.expression.ComparisonExpression.java
License:Open Source License
public void compile(MethodVisitor mv, CompileContext compileContext) throws CompileException { // make sure we are at the right source line compileContext.notifySourceLine(line); Expression oper0 = getOperand(0); Expression oper1 = getOperand(1); int removed = 0; // evaluate the operands and ensure the reuslt is of the correct type for comparison adds 2 oper0.compile(mv, compileContext);//from w w w. j av a2 s .co m compileTypeConversion(oper0.getType(), comparisonType, mv, compileContext); oper1.compile(mv, compileContext); compileTypeConversion(oper1.getType(), comparisonType, mv, compileContext); // now do the appropriate type of comparison if (comparisonType == type.B || comparisonType == type.S || comparisonType == type.S || comparisonType == type.I) { Label elsetarget = new Label(); Label endtarget = new Label(); // we remove 2 words from the stack and then add 1 back removed = 2; switch (oper) { case LT: mv.visitJumpInsn(Opcodes.IF_ICMPGE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case LE: mv.visitJumpInsn(Opcodes.IF_ICMPGT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GT: mv.visitJumpInsn(Opcodes.IF_ICMPLE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GE: mv.visitJumpInsn(Opcodes.IF_ICMPLT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case EQ: mv.visitJumpInsn(Opcodes.IF_ICMPNE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case NE: mv.visitJumpInsn(Opcodes.IF_ICMPEQ, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; } } else if (comparisonType == type.J || comparisonType == type.F || comparisonType == type.D) { if (comparisonType == type.J) { mv.visitInsn(Opcodes.LCMP); // we remove four words from the stack and add 1 back removed = 4; } else if (comparisonType == type.F) { // we remove two words from the stack and add 1 back removed = 2; mv.visitInsn(Opcodes.FCMPG); } else if (comparisonType == type.D) { // we remove four words from the stack and add 1 back removed = 4; mv.visitInsn(Opcodes.DCMPG); } Label elsetarget = new Label(); Label endtarget = new Label(); switch (oper) { case LT: mv.visitJumpInsn(Opcodes.IFGE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case LE: mv.visitJumpInsn(Opcodes.IFGT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GT: mv.visitJumpInsn(Opcodes.IFLE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GE: mv.visitJumpInsn(Opcodes.IFLT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case EQ: mv.visitJumpInsn(Opcodes.IFNE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case NE: mv.visitJumpInsn(Opcodes.IFEQ, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; } } else if (comparable) { // we add a further two words setting up the relevant test then remove them // and also remove the original two words replacing them with a single word removed = 4; compileContext.addStackCount(2); // we need to deal with null values correctly // if op1 == null || op2 == null // then // EQ: // push value1 == value2 // NE: // push value1 != value2 // ow: // push false // else // execute compareTo or equals and test for the desired outcome // end if Label splittarget = new Label(); // else Label jointarget = new Label(); // end if mv.visitInsn(Opcodes.DUP2); // [... op1, op2 ] ==> [... op1, op2, op1, op2] mv.visitInsn(Opcodes.POP); // [... op1, op2, op1, op2 ] ==> [... op1, op2, op1] // if op1 == null mv.visitJumpInsn(Opcodes.IFNULL, splittarget); // [... op1, op2, op1] ==> [... op1, op2] mv.visitInsn(Opcodes.DUP); // [... op1, op2 ] ==> [... op1, op2, op2] // || op2 == null mv.visitJumpInsn(Opcodes.IFNULL, splittarget); // [... op1, op2, op2] ==> [... op1, op2] // so, it is ok to call compareTo leaving an int or equals leaving a boolean if (oper != EQ && oper != NE) { mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Comparable", "compareTo", "(Ljava/lang/Object;)I"); } else { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); } // now if we did a compareTo we need to generate the required boolean Label elsetarget = new Label(); Label endtarget = new Label(); // if needed the convert the compareTo result to the required boolean outcome switch (oper) { case LT: mv.visitJumpInsn(Opcodes.IFGE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case LE: mv.visitJumpInsn(Opcodes.IFGT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GT: mv.visitJumpInsn(Opcodes.IFLE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GE: mv.visitJumpInsn(Opcodes.IFLT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case NE: mv.visitJumpInsn(Opcodes.IFEQ, elsetarget); mv.visitLdcInsn(false); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(true); mv.visitLabel(endtarget); break; } // skip to the join point mv.visitJumpInsn(Opcodes.GOTO, jointarget); // label the split point mv.visitLabel(splittarget); if (oper == EQ) { elsetarget = new Label(); endtarget = new Label(); mv.visitJumpInsn(Opcodes.IF_ACMPEQ, elsetarget); mv.visitLdcInsn(false); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(true); mv.visitLabel(endtarget); } else if (oper == NE) { elsetarget = new Label(); endtarget = new Label(); mv.visitJumpInsn(Opcodes.IF_ACMPNE, elsetarget); mv.visitLdcInsn(false); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(true); mv.visitLabel(endtarget); } else { // pop the operands and stack false mv.visitInsn(Opcodes.POP2); mv.visitLdcInsn(false); } // label the join point mv.visitLabel(jointarget); } else if (comparisonType == Type.Z) { // unboxed booleans need special treatment // we remove two words replacing them with a single word removed = 2; Label elsetarget = new Label(); Label endtarget = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, elsetarget); // on this branch for EQ the stacked value is what we need and for NE // the stacked value needs flipping if (oper == NE) { Label elsetarget2 = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, elsetarget2); mv.visitLdcInsn(false); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget2); mv.visitLdcInsn(true); } mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); // on this branch for NE the stacked value is what we need and for EQ // the stacked value needs flipping if (oper == EQ) { Label elsetarget2 = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, elsetarget2); mv.visitLdcInsn(false); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget2); mv.visitLdcInsn(true); } mv.visitLabel(endtarget); } else if (comparisonType == Type.BOOLEAN) { // boxed booleans need special treatment // we remove two words replacing them with a single word removed = 2; Label elsetarget = new Label(); Label endtarget = new Label(); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java.lang.Boolean", "equals", "(Ljava/lang/Boolean;)Z"); if (oper == NE) { mv.visitJumpInsn(Opcodes.IFEQ, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); } } else { // we remove two words replacing them with a single word removed = 2; Label elsetarget = new Label(); Label endtarget = new Label(); if (oper == EQ) { mv.visitJumpInsn(Opcodes.IF_ACMPNE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); } else { mv.visitJumpInsn(Opcodes.IF_ACMPEQ, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); } } compileContext.addStackCount(1 - removed); }