/**
   * Checks a given class
   *
   * @param cr a <code>ClassReader</code> that contains bytecode for the analysis.
   * @param loader a <code>ClassLoader</code> which will be used to load referenced classes. This is
   *     useful if you are verifiying multiple interdependent classes.
   * @param dump true if bytecode should be printed out not only when errors are found.
   * @param pw write where results going to be printed
   */
  public static void verify(
      final ClassReader cr, final ClassLoader loader, final boolean dump, final PrintWriter pw) {
    ClassNode cn = new ClassNode();
    cr.accept(new CheckClassAdapter(cn, false), ClassReader.SKIP_DEBUG);

    Type syperType = cn.superName == null ? null : Type.getObjectType(cn.superName);
    List methods = cn.methods;

    List interfaces = new ArrayList();
    for (Iterator i = cn.interfaces.iterator(); i.hasNext(); ) {
      interfaces.add(Type.getObjectType(i.next().toString()));
    }

    for (int i = 0; i < methods.size(); ++i) {
      MethodNode method = (MethodNode) methods.get(i);
      SimpleVerifier verifier =
          new SimpleVerifier(Type.getObjectType(cn.name), syperType, interfaces, false);
      Analyzer a = new Analyzer(verifier);
      if (loader != null) {
        verifier.setClassLoader(loader);
      }
      try {
        a.analyze(cn.name, method);
        if (!dump) {
          continue;
        }
      } catch (Exception e) {
        e.printStackTrace(pw);
      }
      printAnalyzerResult(method, a, pw);
    }
    pw.flush();
  }
Esempio n. 2
0
/**
 * If thrown under the context of an active transaction the current transaction context will be
 * rolled back and a new retry will be initialized.
 *
 * @author Guy Korland
 * @since 1.0
 */
@ExcludeInternal
public class TransactionException extends RuntimeException {

  public static final String TRANSACTION_EXCEPTION_INTERNAL =
      Type.getInternalName(TransactionException.class);
  public static final TransactionException STATIC_TRANSACTION = new TransactionException();

  public TransactionException() {}

  public TransactionException(String msg) {
    super(msg);
  }

  public TransactionException(Throwable cause) {
    super(cause);
  }

  @Override
  public Throwable fillInStackTrace() {
    return null;
  } // light exception with no stack trace

  @Override
  public Throwable initCause(Throwable cause) {
    throw new IllegalStateException("Can't set cause.");
  }
}
  @Override
  public void visitCode() {
    mv.visitCode();

    if (!remote) return;

    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, classInternalName, ITypeInternalName.$HY$_STATE, "I");
    mv.visitInsn(ITypeInternalName.DEFAULT_STATE);
    Label l1 = new Label();
    mv.visitJumpInsn(Opcodes.IF_ICMPEQ, l1);

    Type[] types = Type.getArgumentTypes(desc);
    mv.visitIntInsn(Opcodes.BIPUSH, types.length);
    mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
    mv.visitInsn(Opcodes.DUP);
    int offset = types.length + 1;
    mv.visitVarInsn(Opcodes.ASTORE, offset);

    for (int i = 0; i < types.length; ++i) {
      mv.visitVarInsn(Opcodes.ALOAD, offset);
      mv.visitIntInsn(Opcodes.BIPUSH, i);
      switch (types[i].getSort()) {
        case Type.BOOLEAN:
        case Type.BYTE:
        case Type.CHAR:
        case Type.SHORT:
        case Type.INT:
          mv.visitVarInsn(Opcodes.ILOAD, i + 1);
          mv.visitMethodInsn(
              Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
          break;
        case Type.LONG:
          mv.visitVarInsn(Opcodes.LLOAD, i + 1);
          mv.visitMethodInsn(
              Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;");
          break;
        case Type.FLOAT:
          mv.visitVarInsn(Opcodes.FLOAD, i + 1);
          mv.visitMethodInsn(
              Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;");
          break;
        case Type.DOUBLE:
          mv.visitVarInsn(Opcodes.DLOAD, i + 1);
          mv.visitMethodInsn(
              Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
          break;
        default:
          mv.visitVarInsn(Opcodes.ALOAD, i + 1);
          break;
      }
      mv.visitInsn(Opcodes.AASTORE);
    }

    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(
        Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
    //		mv.visitMethodInsn(Opcodes.INVOKESTATIC, ITypeInternalName.HYFLOW, "getRemoteCaller",
    // "(Ljava/lang/Class;)L" + ITypeInternalName.REMOTE_CALLER + ";");
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, classInternalName, "id", "Ljava/lang/String;");
    mv.visitLdcInsn(method);
    mv.visitVarInsn(Opcodes.ALOAD, offset);

    //		mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, ITypeInternalName.REMOTE_CALLER, "execute",
    // "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;");

    Type type = Type.getReturnType(desc);
    switch (type.getSort()) {
      case Type.VOID:
        mv.visitInsn(Opcodes.POP);
        mv.visitInsn(Opcodes.RETURN);
        break;
      case Type.BOOLEAN:
        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Boolean");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
        mv.visitInsn(Opcodes.IRETURN);
        break;
      case Type.BYTE:
        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Byte");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B");
        mv.visitInsn(Opcodes.IRETURN);
        break;
      case Type.CHAR:
        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Char");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Char", "charValue", "()C");
        mv.visitInsn(Opcodes.IRETURN);
        break;
      case Type.SHORT:
        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Short");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S");
        mv.visitInsn(Opcodes.IRETURN);
        break;
      case Type.INT:
        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Integer");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I");
        mv.visitInsn(Opcodes.IRETURN);
        break;
      case Type.LONG:
        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Long");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
        mv.visitInsn(Opcodes.LRETURN);
        break;
      case Type.FLOAT:
        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Float");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F");
        mv.visitInsn(Opcodes.FRETURN);
        break;
      case Type.DOUBLE:
        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Double");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D");
        mv.visitInsn(Opcodes.DRETURN);
        break;
      default:
        mv.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName());
        mv.visitInsn(Opcodes.ARETURN);
        break;
    }

    mv.visitLabel(l1);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
  }
Esempio n. 4
0
@ExcludeTM
public final class TribuDSTM {
  public static final String DESC = Type.getDescriptor(TribuDSTM.class);
  public static final String NAME = Type.getInternalName(TribuDSTM.class);

  private static final Locator locator = new SimpleLocator();
  private static DistributedProtocol distProtocol;
  private static GroupCommunication groupComm;
  private static DataPartitioner dataPartitioner;
  private static GroupPartitioner groupPartitioner;
  private static boolean partial;

  private static Class<? extends Group> groupClass;
  private static Class<? extends DistributedContext> ctxClass;

  static {
    checkRuntimeMode("false");
    initReplicationProtocol();
    initTransactionContext();
    if (partial) {
      initPartitioners();
    }
  }

  /*
   * Defer the initialization of group communication until the actual
   * application is executing. Apparently, explicit class loading during the
   * execution of an agent is only supported in JDK 7.
   */
  public static final String INIT_METHOD_NAME = "init";
  public static final String INIT_METHOD_DESC = "()" + Type.VOID_TYPE.getDescriptor();

  public static void init() {
    initGroupCommunication();
    if (partial) {
      groupPartitioner.partitionGroups(
          groupComm.getMembers(), Integer.getInteger("tribu.groups", 1));
      dataPartitioner.init();
    }
    distProtocol.init();
  }

  public static final String CLOSE_METHOD_NAME = "close";
  public static final String CLOSE_METHOD_DESC = "()" + Type.VOID_TYPE.getDescriptor();

  public static void close() {
    groupComm.close();
  }

  private static void initGroupCommunication() {
    String className =
        System.getProperty(
            "tribu.groupcommunication.class",
            "org.deuce.distribution.groupcomm.jgroups.JGroupsGroupCommunication");

    try {
      @SuppressWarnings("unchecked")
      Class<? extends GroupCommunication> groupCommClass =
          (Class<? extends GroupCommunication>) Class.forName(className);
      groupComm = groupCommClass.newInstance();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(-1);
    }
  }

  @SuppressWarnings("unchecked")
  private static void initTransactionContext() {
    String className =
        System.getProperty(
            "org.deuce.transaction.contextClass", "org.deuce.transaction.tl2.Context");

    try {
      ctxClass = (Class<? extends DistributedContext>) Class.forName(className);
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(-1);
    }
  }

  private static void initReplicationProtocol() {
    String className =
        System.getProperty(
            "tribu.distributed.protocolClass",
            "org.deuce.distribution.replication.full.protocol.nonvoting.NonVoting");

    try {
      @SuppressWarnings("unchecked")
      Class<? extends DistributedProtocol> distProtocolClass =
          (Class<? extends DistributedProtocol>) Class.forName(className);
      distProtocol = distProtocolClass.newInstance();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(-1);
    }
  }

  @SuppressWarnings("unchecked")
  private static void initPartitioners() {
    String groupPartClass =
        System.getProperty(
            "tribu.distributed.GroupPartitionerClass",
            "org.deuce.distribution.replication.partitioner.group.RandomGroupPartitioner");
    String dataPartClass =
        System.getProperty(
            "tribu.distributed.DataPartitionerClass",
            "org.deuce.distribution.replication.partitioner.data.SimpleDataPartitioner");
    String gClass =
        System.getProperty(
            "tribu.distributed.GroupClass",
            "org.deuce.distribution.replication.group.PartialReplicationGroup");

    try {
      Class<? extends GroupPartitioner> groupPart =
          (Class<? extends GroupPartitioner>) Class.forName(groupPartClass);
      groupPartitioner = groupPart.newInstance();

      Class<? extends DataPartitioner> dataPart =
          (Class<? extends DataPartitioner>) Class.forName(dataPartClass);
      dataPartitioner = dataPart.newInstance();

      groupClass = (Class<? extends Group>) Class.forName(gClass);
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(-1);
    }
  }

  private static void checkRuntimeMode(String partialDefault) {
    partial =
        Boolean.parseBoolean(
            System.getProperty("tribu.distributed.PartialReplicationMode", partialDefault));
  }

  public static final List<Address> getAllMembers() {
    return groupComm.getMembers();
  }

  public static final Class<? extends DistributedContext> getContextClass() {
    return ctxClass;
  }

  public static final Class<? extends Group> getGroupClass() {
    return groupClass;
  }

  public static final Locator getLocator() {
    return locator;
  }

  public static final UniqueObject getObject(ObjectMetadata metadata) {
    return locator.get(metadata);
  }

  public static final void putObject(ObjectMetadata metadata, UniqueObject obj) {
    locator.put(metadata, obj);
  }

  public static final void onContextCreation(DistributedContext ctx) {
    distProtocol.onTxContextCreation(ctx);
  }

  public static final void onTxBegin(DistributedContext ctx) {
    distProtocol.onTxBegin(ctx);
  }

  public static final void onTxFinished(DistributedContext ctx, boolean committed) {
    distProtocol.onTxFinished(ctx, committed);
  }

  public static final void onTxCommit(DistributedContext ctx) {
    distProtocol.onTxCommit(ctx);
  }

  public static final Object onTxRead(
      DistributedContext ctx, ObjectMetadata metadata, Object value) {
    return distProtocol.onTxRead(ctx, metadata, value);
  }

  public static final void onTxWrite(
      DistributedContext ctx, ObjectMetadata metadata, UniqueObject obj) {
    distProtocol.onTxWrite(ctx, metadata, obj);
  }

  public static final String GETSERIALIZER_METHOD_NAME = "getObjectSerializer";
  public static final String GETSERIALIZER_METHOD_DESC = "()" + ObjectSerializer.DESC;

  public static final ObjectSerializer getObjectSerializer() {
    return distProtocol.getObjectSerializer();
  }

  public static final void sendTotalOrdered(byte[] payload) {
    groupComm.sendTotalOrdered(payload);
  }

  public static final void sendTotalOrdered(byte[] payload, Group groups) {
    groupComm.sendTotalOrdered(payload, groups);
  }

  public static final void sendReliably(byte[] payload) {
    groupComm.sendReliably(payload);
  }

  public static final void sendTo(byte[] payload, Address addr) {
    groupComm.sendTo(payload, addr);
  }

  public static final boolean isLocalAddress(Address addr) {
    return groupComm.isLocal(addr);
  }

  public static final void subscribeDeliveries(DeliverySubscriber subscriber) {
    groupComm.subscribeDelivery(subscriber);
  }

  public static final void subscribeOptimisticDeliveries(OptimisticDeliverySubscriber subscriber) {
    groupComm.subscribeOptimisticDelivery(subscriber);
  }

  public static final Address getLocalAddress() {
    return groupComm.getAddress();
  }

  public static final Group getLocalGroup() {
    return groupPartitioner.getMyGroup();
  }

  public static final List<Group> getAllGroups() {
    return groupPartitioner.getGroups();
  }

  public static final Group publishObjectTo(UniqueObject obj) {
    return dataPartitioner.publishTo(obj);
  }

  public static final boolean isLocalGroup(Group group) {
    return getLocalGroup().equals(group);
  }
}
Esempio n. 5
0
  public void execute(final AbstractInsnNode insn, final Interpreter interpreter)
      throws AnalyzerException {
    Value value1, value2, value3, value4;
    List values;
    int var;

    switch (insn.getOpcode()) {
      case Opcodes.NOP:
        break;
      case Opcodes.ACONST_NULL:
      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.LCONST_0:
      case Opcodes.LCONST_1:
      case Opcodes.FCONST_0:
      case Opcodes.FCONST_1:
      case Opcodes.FCONST_2:
      case Opcodes.DCONST_0:
      case Opcodes.DCONST_1:
      case Opcodes.BIPUSH:
      case Opcodes.SIPUSH:
      case Opcodes.LDC:
        push(interpreter.newOperation(insn));
        break;
      case Opcodes.ILOAD:
      case Opcodes.LLOAD:
      case Opcodes.FLOAD:
      case Opcodes.DLOAD:
      case Opcodes.ALOAD:
        push(interpreter.copyOperation(insn, getLocal(((VarInsnNode) insn).var)));
        break;
      case Opcodes.IALOAD:
      case Opcodes.LALOAD:
      case Opcodes.FALOAD:
      case Opcodes.DALOAD:
      case Opcodes.AALOAD:
      case Opcodes.BALOAD:
      case Opcodes.CALOAD:
      case Opcodes.SALOAD:
        value2 = pop();
        value1 = pop();
        push(interpreter.binaryOperation(insn, value1, value2));
        break;
      case Opcodes.ISTORE:
      case Opcodes.LSTORE:
      case Opcodes.FSTORE:
      case Opcodes.DSTORE:
      case Opcodes.ASTORE:
        value1 = interpreter.copyOperation(insn, pop());
        var = ((VarInsnNode) insn).var;
        setLocal(var, value1);
        if (value1.getSize() == 2) {
          setLocal(var + 1, interpreter.newValue(null));
        }
        if (var > 0) {
          Value local = getLocal(var - 1);
          if (local != null && local.getSize() == 2) {
            setLocal(var - 1, interpreter.newValue(null));
          }
        }
        break;
      case Opcodes.IASTORE:
      case Opcodes.LASTORE:
      case Opcodes.FASTORE:
      case Opcodes.DASTORE:
      case Opcodes.AASTORE:
      case Opcodes.BASTORE:
      case Opcodes.CASTORE:
      case Opcodes.SASTORE:
        value3 = pop();
        value2 = pop();
        value1 = pop();
        interpreter.ternaryOperation(insn, value1, value2, value3);
        break;
      case Opcodes.POP:
        if (pop().getSize() == 2) {
          throw new AnalyzerException(insn, "Illegal use of POP");
        }
        break;
      case Opcodes.POP2:
        if (pop().getSize() == 1) {
          if (pop().getSize() != 1) {
            throw new AnalyzerException(insn, "Illegal use of POP2");
          }
        }
        break;
      case Opcodes.DUP:
        value1 = pop();
        if (value1.getSize() != 1) {
          throw new AnalyzerException(insn, "Illegal use of DUP");
        }
        push(value1);
        push(interpreter.copyOperation(insn, value1));
        break;
      case Opcodes.DUP_X1:
        value1 = pop();
        value2 = pop();
        if (value1.getSize() != 1 || value2.getSize() != 1) {
          throw new AnalyzerException(insn, "Illegal use of DUP_X1");
        }
        push(interpreter.copyOperation(insn, value1));
        push(value2);
        push(value1);
        break;
      case Opcodes.DUP_X2:
        value1 = pop();
        if (value1.getSize() == 1) {
          value2 = pop();
          if (value2.getSize() == 1) {
            value3 = pop();
            if (value3.getSize() == 1) {
              push(interpreter.copyOperation(insn, value1));
              push(value3);
              push(value2);
              push(value1);
              break;
            }
          } else {
            push(interpreter.copyOperation(insn, value1));
            push(value2);
            push(value1);
            break;
          }
        }
        throw new AnalyzerException(insn, "Illegal use of DUP_X2");
      case Opcodes.DUP2:
        value1 = pop();
        if (value1.getSize() == 1) {
          value2 = pop();
          if (value2.getSize() == 1) {
            push(value2);
            push(value1);
            push(interpreter.copyOperation(insn, value2));
            push(interpreter.copyOperation(insn, value1));
            break;
          }
        } else {
          push(value1);
          push(interpreter.copyOperation(insn, value1));
          break;
        }
        throw new AnalyzerException(insn, "Illegal use of DUP2");
      case Opcodes.DUP2_X1:
        value1 = pop();
        if (value1.getSize() == 1) {
          value2 = pop();
          if (value2.getSize() == 1) {
            value3 = pop();
            if (value3.getSize() == 1) {
              push(interpreter.copyOperation(insn, value2));
              push(interpreter.copyOperation(insn, value1));
              push(value3);
              push(value2);
              push(value1);
              break;
            }
          }
        } else {
          value2 = pop();
          if (value2.getSize() == 1) {
            push(interpreter.copyOperation(insn, value1));
            push(value2);
            push(value1);
            break;
          }
        }
        throw new AnalyzerException(insn, "Illegal use of DUP2_X1");
      case Opcodes.DUP2_X2:
        value1 = pop();
        if (value1.getSize() == 1) {
          value2 = pop();
          if (value2.getSize() == 1) {
            value3 = pop();
            if (value3.getSize() == 1) {
              value4 = pop();
              if (value4.getSize() == 1) {
                push(interpreter.copyOperation(insn, value2));
                push(interpreter.copyOperation(insn, value1));
                push(value4);
                push(value3);
                push(value2);
                push(value1);
                break;
              }
            } else {
              push(interpreter.copyOperation(insn, value2));
              push(interpreter.copyOperation(insn, value1));
              push(value3);
              push(value2);
              push(value1);
              break;
            }
          }
        } else {
          value2 = pop();
          if (value2.getSize() == 1) {
            value3 = pop();
            if (value3.getSize() == 1) {
              push(interpreter.copyOperation(insn, value1));
              push(value3);
              push(value2);
              push(value1);
              break;
            }
          } else {
            push(interpreter.copyOperation(insn, value1));
            push(value2);
            push(value1);
            break;
          }
        }
        throw new AnalyzerException(insn, "Illegal use of DUP2_X2");
      case Opcodes.SWAP:
        value2 = pop();
        value1 = pop();
        if (value1.getSize() != 1 || value2.getSize() != 1) {
          throw new AnalyzerException(insn, "Illegal use of SWAP");
        }
        push(interpreter.copyOperation(insn, value2));
        push(interpreter.copyOperation(insn, value1));
        break;
      case Opcodes.IADD:
      case Opcodes.LADD:
      case Opcodes.FADD:
      case Opcodes.DADD:
      case Opcodes.ISUB:
      case Opcodes.LSUB:
      case Opcodes.FSUB:
      case Opcodes.DSUB:
      case Opcodes.IMUL:
      case Opcodes.LMUL:
      case Opcodes.FMUL:
      case Opcodes.DMUL:
      case Opcodes.IDIV:
      case Opcodes.LDIV:
      case Opcodes.FDIV:
      case Opcodes.DDIV:
      case Opcodes.IREM:
      case Opcodes.LREM:
      case Opcodes.FREM:
      case Opcodes.DREM:
        value2 = pop();
        value1 = pop();
        push(interpreter.binaryOperation(insn, value1, value2));
        break;
      case Opcodes.INEG:
      case Opcodes.LNEG:
      case Opcodes.FNEG:
      case Opcodes.DNEG:
        push(interpreter.unaryOperation(insn, pop()));
        break;
      case Opcodes.ISHL:
      case Opcodes.LSHL:
      case Opcodes.ISHR:
      case Opcodes.LSHR:
      case Opcodes.IUSHR:
      case Opcodes.LUSHR:
      case Opcodes.IAND:
      case Opcodes.LAND:
      case Opcodes.IOR:
      case Opcodes.LOR:
      case Opcodes.IXOR:
      case Opcodes.LXOR:
        value2 = pop();
        value1 = pop();
        push(interpreter.binaryOperation(insn, value1, value2));
        break;
      case Opcodes.IINC:
        var = ((IincInsnNode) insn).var;
        setLocal(var, interpreter.unaryOperation(insn, getLocal(var)));
        break;
      case Opcodes.I2L:
      case Opcodes.I2F:
      case Opcodes.I2D:
      case Opcodes.L2I:
      case Opcodes.L2F:
      case Opcodes.L2D:
      case Opcodes.F2I:
      case Opcodes.F2L:
      case Opcodes.F2D:
      case Opcodes.D2I:
      case Opcodes.D2L:
      case Opcodes.D2F:
      case Opcodes.I2B:
      case Opcodes.I2C:
      case Opcodes.I2S:
        push(interpreter.unaryOperation(insn, pop()));
        break;
      case Opcodes.LCMP:
      case Opcodes.FCMPL:
      case Opcodes.FCMPG:
      case Opcodes.DCMPL:
      case Opcodes.DCMPG:
        value2 = pop();
        value1 = pop();
        push(interpreter.binaryOperation(insn, value1, value2));
        break;
      case Opcodes.IFEQ:
      case Opcodes.IFNE:
      case Opcodes.IFLT:
      case Opcodes.IFGE:
      case Opcodes.IFGT:
      case Opcodes.IFLE:
        interpreter.unaryOperation(insn, 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:
        value2 = pop();
        value1 = pop();
        interpreter.binaryOperation(insn, value1, value2);
        break;
      case Opcodes.GOTO:
        break;
      case Opcodes.JSR:
        push(interpreter.newOperation(insn));
        break;
      case Opcodes.RET:
        break;
      case Opcodes.TABLESWITCH:
      case Opcodes.LOOKUPSWITCH:
        interpreter.unaryOperation(insn, pop());
        break;
      case Opcodes.IRETURN:
      case Opcodes.LRETURN:
      case Opcodes.FRETURN:
      case Opcodes.DRETURN:
      case Opcodes.ARETURN:
        value1 = pop();
        interpreter.unaryOperation(insn, value1);
        interpreter.returnOperation(insn, value1, returnValue);
        break;
      case Opcodes.RETURN:
        if (returnValue != null) {
          throw new AnalyzerException(insn, "Incompatible return type");
        }
        break;
      case Opcodes.GETSTATIC:
        push(interpreter.newOperation(insn));
        break;
      case Opcodes.PUTSTATIC:
        interpreter.unaryOperation(insn, pop());
        break;
      case Opcodes.GETFIELD:
        push(interpreter.unaryOperation(insn, pop()));
        break;
      case Opcodes.PUTFIELD:
        value2 = pop();
        value1 = pop();
        interpreter.binaryOperation(insn, value1, value2);
        break;
      case Opcodes.INVOKEVIRTUAL:
      case Opcodes.INVOKESPECIAL:
      case Opcodes.INVOKESTATIC:
      case Opcodes.INVOKEINTERFACE:
      case Opcodes.INVOKEDYNAMIC:
        values = new ArrayList();
        String desc = ((MethodInsnNode) insn).desc;
        for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
          values.add(0, pop());
        }
        if (insn.getOpcode() != Opcodes.INVOKESTATIC && insn.getOpcode() != Opcodes.INVOKEDYNAMIC) {
          values.add(0, pop());
        }
        if (Type.getReturnType(desc) == Type.VOID_TYPE) {
          interpreter.naryOperation(insn, values);
        } else {
          push(interpreter.naryOperation(insn, values));
        }
        break;
      case Opcodes.NEW:
        push(interpreter.newOperation(insn));
        break;
      case Opcodes.NEWARRAY:
      case Opcodes.ANEWARRAY:
      case Opcodes.ARRAYLENGTH:
        push(interpreter.unaryOperation(insn, pop()));
        break;
      case Opcodes.ATHROW:
        interpreter.unaryOperation(insn, pop());
        break;
      case Opcodes.CHECKCAST:
      case Opcodes.INSTANCEOF:
        push(interpreter.unaryOperation(insn, pop()));
        break;
      case Opcodes.MONITORENTER:
      case Opcodes.MONITOREXIT:
        interpreter.unaryOperation(insn, pop());
        break;
      case Opcodes.MULTIANEWARRAY:
        values = new ArrayList();
        for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) {
          values.add(0, pop());
        }
        push(interpreter.naryOperation(insn, values));
        break;
      case Opcodes.IFNULL:
      case Opcodes.IFNONNULL:
        interpreter.unaryOperation(insn, pop());
        break;
      default:
        throw new RuntimeException("Illegal opcode " + insn.getOpcode());
    }
  }