List of usage examples for org.objectweb.asm Frame push
private void push(final int abstractType)
From source file:kilim.analysis.BasicBlock.java
License:Open Source License
void interpret() { Value v, v1, v2, v3, v4;// w ww . jav a 2 s .com Frame frame = startFrame.dup(); if (isCatchHandler()) { // When an exception is thrown, the stack is cleared // and the thrown exception is pushed into the stack frame.clearStack(); frame.push(Value.make(startPos, caughtExceptionType)); } else if (hasFlag(IS_SUBROUTINE)) { // The target of a JSR instruction has a JVM-internal // return address which we model with a type of its // own frame.push(Value.make(startPos, D_RETURN_ADDRESS)); } String componentType = null; @SuppressWarnings("unused") boolean canThrowException = false; boolean propagateFrame = true; int i = 0; try { for (i = startPos; i <= endPos; i++) { AbstractInsnNode ain = getInstruction(i); int opcode = ain.getOpcode(); int val, var; switch (opcode) { case NOP: break; case ACONST_NULL: frame.push(Value.make(i, D_NULL)); break; case ICONST_M1: case ICONST_0: case ICONST_1: case ICONST_2: case ICONST_3: case ICONST_4: case ICONST_5: frame.push(Value.make(i, D_INT, new Integer(opcode - ICONST_0))); break; case LCONST_0: case LCONST_1: frame.push(Value.make(i, D_LONG, new Long(opcode - LCONST_0))); break; case ILOAD: case LLOAD: case FLOAD: case DLOAD: case ALOAD: var = ((VarInsnNode) ain).var; v = frame.getLocal(var, opcode); frame.push(v); break; case FCONST_0: case FCONST_1: case FCONST_2: frame.push(Value.make(i, D_FLOAT, new Float(opcode - FCONST_0))); break; case DCONST_0: case DCONST_1: frame.push(Value.make(i, D_DOUBLE, new Double(opcode - DCONST_0))); break; case BIPUSH: val = ((IntInsnNode) ain).operand; frame.push(Value.make(i, D_BYTE, new Integer(val))); break; case SIPUSH: val = ((IntInsnNode) ain).operand; frame.push(Value.make(i, D_SHORT, new Integer(val))); break; case LDC: Object cval = ((LdcInsnNode) ain).cst; frame.push(Value.make(i, TypeDesc.getTypeDesc(cval), cval)); break; case IALOAD: case LALOAD: case FALOAD: case DALOAD: case AALOAD: case BALOAD: case CALOAD: case SALOAD: canThrowException = true; frame.popWord(); // pop index v = frame.popWord(); // array ref frame.push(Value.make(i, TypeDesc.getComponentType(v.getTypeDesc()))); // push // component // of // array break; case ISTORE: case LSTORE: case FSTORE: case DSTORE: case ASTORE: v1 = frame.pop(); var = ((VarInsnNode) ain).var; frame.setLocal(var, v1); break; case IASTORE: case LASTORE: case FASTORE: case DASTORE: case AASTORE: case BASTORE: case CASTORE: case SASTORE: canThrowException = true; frame.popn(3); break; case POP: frame.popWord(); break; case POP2: if (frame.pop().isCategory1()) { frame.popWord(); } break; case DUP: // ... w => ... w w v = frame.popWord(); frame.push(v); frame.push(v); break; case DUP_X1: // Insert top word beneath the next word // .. w2 w1 => .. w1 w2 w1 v1 = frame.popWord(); v2 = frame.popWord(); frame.push(v1); frame.push(v2); frame.push(v1); break; case DUP_X2: // Insert top word beneath the next two words (or dword) v1 = frame.popWord(); v2 = frame.pop(); if (v2.isCategory1()) { v3 = frame.pop(); if (v3.isCategory1()) { // w3,w2,w1 => w1,w3,w2,w1 frame.push(v1); frame.push(v3); frame.push(v2); frame.push(v1); break; } } else { // dw2,w1 => w1,dw2,w1 frame.push(v1); frame.push(v2); frame.push(v1); break; } throw new InternalError("Illegal use of DUP_X2"); case DUP2: // duplicate top two words (or dword) v1 = frame.pop(); if (v1.isCategory1()) { v2 = frame.pop(); if (v2.isCategory1()) { // w2,w1 => w2,w1,w2,w1 frame.push(v2); frame.push(v1); frame.push(v2); frame.push(v1); break; } } else { // dw1 => dw1,dw1 frame.push(v1); frame.push(v1); break; } throw new InternalError("Illegal use of DUP2"); case DUP2_X1: // insert two words (or dword) beneath next word v1 = frame.pop(); if (v1.isCategory1()) { v2 = frame.pop(); if (v2.isCategory1()) { v3 = frame.popWord(); // w3,w2,w1 => w2,w1,w3,w2,w1 frame.push(v2); frame.push(v1); frame.push(v3); frame.push(v2); frame.push(v1); break; } } else { // TypeDesc.isDoubleWord(t1) // w2,dw1 => dw1,w2,dw1 v2 = frame.popWord(); frame.push(v1); frame.push(v2); frame.push(v1); break; } throw new InternalError("Illegal use of DUP2_X1"); case DUP2_X2: // insert two words (or dword) beneath next two words (or // dword) v1 = frame.pop(); if (v1.isCategory1()) { v2 = frame.pop(); if (v2.isCategory1()) { v3 = frame.pop(); if (v3.isCategory1()) { v4 = frame.pop(); if (v4.isCategory1()) { // w4,w3,w2,w1 => w2,w1,w4,w3,w2,w1 frame.push(v2); frame.push(v1); frame.push(v4); frame.push(v3); frame.push(v2); frame.push(v1); break; } } else { // TypeDesc.isDoubleWord(t3) // dw3,w2,w1 => w2,w1,dw3,w2,w1 frame.push(v2); frame.push(v1); frame.push(v3); frame.push(v2); frame.push(v1); break; } } } else { // TypeDesc.isDoubleWord(t1) v2 = frame.pop(); if (v2.isCategory1()) { v3 = frame.pop(); if (v3.isCategory1()) { // w3,w2,dw1 => dw1,w3,w2,dw1 frame.push(v1); frame.push(v3); frame.push(v2); frame.push(v1); break; } } else { // dw2,dw1 => dw1,dw2,dw1 frame.push(v1); frame.push(v2); frame.push(v1); break; } } throw new InternalError("Illegal use of DUP2_X2"); case SWAP: // w2, w1 => w1, w2 v1 = frame.popWord(); v2 = frame.popWord(); frame.push(v1); frame.push(v2); break; case IDIV: case IREM: case LDIV: case LREM: frame.pop(); // See next case canThrowException = true; break; case IADD: case LADD: case FADD: case DADD: case ISUB: case LSUB: case FSUB: case DSUB: case IMUL: case LMUL: case FMUL: case DMUL: case FDIV: case DDIV: case FREM: case DREM: case ISHL: case LSHL: case ISHR: case LSHR: case IUSHR: case LUSHR: case IAND: case LAND: case IOR: case LOR: case IXOR: case LXOR: // Binary op. frame.pop(); v = frame.pop(); // The result is always the same type as the first arg frame.push(Value.make(i, v.getTypeDesc())); break; case LCMP: case FCMPL: case FCMPG: case DCMPL: case DCMPG: frame.popn(2); frame.push(Value.make(i, D_INT)); break; case INEG: case LNEG: case FNEG: case DNEG: v = frame.pop(); frame.push(Value.make(i, v.getTypeDesc())); break; case IINC: var = ((IincInsnNode) ain).var; frame.setLocal(var, Value.make(i, D_INT)); break; case I2L: case F2L: case D2L: frame.pop(); frame.push(Value.make(i, D_LONG)); break; case I2D: case L2D: case F2D: frame.pop(); frame.push(Value.make(i, D_DOUBLE)); break; case I2F: case L2F: case D2F: frame.pop(); frame.push(Value.make(i, D_FLOAT)); break; case L2I: case F2I: case D2I: frame.pop(); frame.push(Value.make(i, D_INT)); break; case I2B: frame.popWord(); frame.push(Value.make(i, D_BOOLEAN)); break; case I2C: frame.popWord(); frame.push(Value.make(i, D_CHAR)); break; case I2S: frame.popWord(); frame.push(Value.make(i, D_SHORT)); break; case IFEQ: case IFNE: case IFLT: case IFGE: case IFGT: case IFLE: case IFNULL: case IFNONNULL: frame.popWord(); break; case IF_ICMPEQ: case IF_ICMPNE: case IF_ICMPLT: case IF_ICMPGE: case IF_ICMPGT: case IF_ICMPLE: case IF_ACMPEQ: case IF_ACMPNE: frame.popn(2); break; case GOTO: case JSR: // note: the targetBB pushes the return address // itself // because it is marked with isSubroutine case RET: break; case TABLESWITCH: case LOOKUPSWITCH: frame.pop(); break; case IRETURN: case LRETURN: case FRETURN: case DRETURN: case ARETURN: case RETURN: canThrowException = true; if (opcode != RETURN) { frame.pop(); } if (frame.stacklen != 0) { throw new InternalError("stack non null at method return"); } break; case GETSTATIC: canThrowException = true; v = Value.make(i, TypeDesc.getInterned(((FieldInsnNode) ain).desc)); frame.push(v); break; case PUTSTATIC: canThrowException = true; frame.pop(); break; case GETFIELD: canThrowException = true; v1 = frame.pop(); v = Value.make(i, TypeDesc.getInterned(((FieldInsnNode) ain).desc)); //if (TypeDesc.isRefType(v.getTypeDesc())) { // System.out.println("GETFIELD " + ((FieldInsnNode)ain).name + ": " + v + "---->" + v1); //} frame.push(v); break; case PUTFIELD: canThrowException = true; v1 = frame.pop(); v = frame.pop(); //if (TypeDesc.isRefType(v.getTypeDesc())) { // System.out.println("PUTFIELD " + ((FieldInsnNode)ain).name + ": " + v + " ----> " + v1); //} break; case INVOKEVIRTUAL: case INVOKESPECIAL: case INVOKESTATIC: case INVOKEINTERFACE: case INVOKEDYNAMIC: // TODO this is new and mysterious // pop args, push return value MethodInsnNode min = ((MethodInsnNode) ain); String desc = min.desc; if (flow.isPausableMethodInsn(min) && frame.numMonitorsActive > 0) { throw new KilimException( "Error: Can not call pausable nethods from within a synchronized block\n" + "Caller: " + this.flow.name + "\nCallee: " + ((MethodInsnNode) ain).name); } canThrowException = true; frame.popn(TypeDesc.getNumArgumentTypes(desc)); if (opcode != INVOKESTATIC) { v = frame.pop(); // "this" ref //assert checkReceiverType(v, min) : "Method " + flow.name + " calls " + min.name + " on a receiver with incompatible type " + v.getTypeDesc() ; } desc = TypeDesc.getReturnTypeDesc(desc); if (desc != D_VOID) { frame.push(Value.make(i, desc)); } break; case NEW: canThrowException = true; v = Value.make(i, TypeDesc.getInterned(((TypeInsnNode) ain).desc)); frame.push(v); break; case NEWARRAY: canThrowException = true; frame.popWord(); int atype = ((IntInsnNode) ain).operand; String t; switch (atype) { case T_BOOLEAN: t = D_ARRAY_BOOLEAN; break; case T_CHAR: t = D_ARRAY_CHAR; break; case T_FLOAT: t = D_ARRAY_FLOAT; break; case T_DOUBLE: t = D_ARRAY_DOUBLE; break; case T_BYTE: t = D_ARRAY_BYTE; break; case T_SHORT: t = D_ARRAY_SHORT; break; case T_INT: t = D_ARRAY_INT; break; case T_LONG: t = D_ARRAY_LONG; break; default: throw new InternalError("Illegal argument to NEWARRAY: " + atype); } frame.push(Value.make(i, t)); break; case ANEWARRAY: canThrowException = true; frame.popWord(); componentType = TypeDesc.getInterned(((TypeInsnNode) ain).desc); v = Value.make(i, TypeDesc.getInterned("[" + componentType)); frame.push(v); break; case ARRAYLENGTH: canThrowException = true; frame.popWord(); frame.push(Value.make(i, D_INT)); break; case ATHROW: canThrowException = true; frame.pop(); propagateFrame = false; break; case CHECKCAST: canThrowException = true; frame.pop(); v = Value.make(i, TypeDesc.getInterned(((TypeInsnNode) ain).desc)); frame.push(v); break; case INSTANCEOF: canThrowException = true; frame.pop(); frame.push(Value.make(i, D_INT)); break; case MONITORENTER: case MONITOREXIT: if (opcode == MONITORENTER) { frame.numMonitorsActive++; } else { frame.numMonitorsActive--; } canThrowException = true; frame.pop(); canThrowException = true; break; case MULTIANEWARRAY: MultiANewArrayInsnNode minode = (MultiANewArrayInsnNode) ain; int dims = minode.dims; frame.popn(dims); componentType = TypeDesc.getInterned(minode.desc); StringBuffer sb = new StringBuffer(componentType.length() + dims); for (int j = 0; j < dims; j++) sb.append('['); sb.append(componentType); v = Value.make(i, TypeDesc.getInterned(sb.toString())); frame.push(v); break; case -1: // TODO this is new and mysterious break; default: assert false : "Unexpected opcode: " + ain.getOpcode(); } } i = -1; // reset for assertion catch block below if (propagateFrame) { mergeSuccessors(frame); } if (handlers != null) { for (Handler handler : handlers) { handler.catchBB.merge(frame, /* localsOnly= */true); // merge // only // locals } canThrowException = false; } } catch (AssertionError ae) { System.err.println("**** Assertion Error analyzing " + flow.classFlow.name + "." + flow.name); System.err.println("Basic block " + this); System.err.println("i = " + i); System.err.println("Frame: " + frame); throw ae; } }