/** * 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(); }
/** * 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); }
@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); } }
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()); } }