List of usage examples for org.objectweb.asm.tree AbstractInsnNode getOpcode
public int getOpcode()
From source file:jaspex.speculation.newspec.FlowFrame.java
License:Open Source License
FlowFrame computeNextFrame(FlowFrame previousFrame, AbstractInsnNode insn) throws AnalyzerException { if (previousFrame == null) throw new NullPointerException("Null previousFrame"); FlowFrame newFrame = newFrame(previousFrame); // Verificar que instruco produz uma frame if (insn.getOpcode() == ATHROW || returnOpcodes.contains(insn.getOpcode())) { throw new AssertionError(); }/* w ww. j a va 2 s .c o m*/ if (!(insn instanceof FrameNode || insn instanceof LabelNode || insn instanceof LineNumberNode)) { try { newFrame.execute(insn, _interpreter); } catch (IndexOutOfBoundsException e) { throw new AnalyzerException(insn, "Error inside computeNextFrame", e); } catch (NullPointerException e) { throw new AnalyzerException(insn, "Error inside computeNextFrame", e); } } return newFrame; }
From source file:jaspex.speculation.newspec.FlowFrame.java
License:Open Source License
@Override public BasicValue copyOperation(AbstractInsnNode insn, BasicValue value) throws AnalyzerException { // DelayGetFutureMethodVisitor.visitVarInsn, verso interpetador int opcode = insn.getOpcode(); if (opcode == DUP2 || opcode == DUP2_X1 || opcode == DUP2_X2 || opcode == POP2) { if (isFuture(value)) { Type t = stripFuture(value).getType(); if (t.equals(Type.LONG_TYPE) || t.equals(Type.DOUBLE_TYPE)) { // Temos de fazer substituio de bytecodes switch (opcode) { case DUP2: opcode = DUP;/*from w w w . j a va 2s. c o m*/ break; case DUP2_X1: opcode = DUP_X1; break; case DUP2_X2: opcode = DUP_X2; break; case POP2: opcode = POP; break; } insn = new InsnNode(opcode); } } } else if (localLoadOpcodes.contains(opcode) && isFuture(value)) { insn = new VarInsnNode(ALOAD, ((VarInsnNode) insn).var); } else if (localStoreOpcodes.contains(opcode) && isFuture(value)) { insn = new VarInsnNode(ASTORE, ((VarInsnNode) insn).var); } return super.copyOperation(insn, value); }
From source file:jaspex.transactifier.ChangeClinitMethodVisitor.java
License:Open Source License
private static boolean clinitIsSafe(Type t) { try {// w w w . j a va2s .com ClassReader cr = new ClassReader(t.commonName()); ClassNode cNode = new ClassNode(); cr.accept(cNode, 0); for (MethodNode method : cNode.methods) { if (!method.name.equals("<clinit>")) continue; // Examinar instruces Iterator<AbstractInsnNode> it = method.instructions.iterator(); while (it.hasNext()) { AbstractInsnNode insn = it.next(); switch (insn.getType()) { case AbstractInsnNode.FRAME: case AbstractInsnNode.INT_INSN: case AbstractInsnNode.JUMP_INSN: case AbstractInsnNode.LABEL: case AbstractInsnNode.LDC_INSN: case AbstractInsnNode.LINE: case AbstractInsnNode.LOOKUPSWITCH_INSN: case AbstractInsnNode.MULTIANEWARRAY_INSN: case AbstractInsnNode.TABLESWITCH_INSN: case AbstractInsnNode.TYPE_INSN: case AbstractInsnNode.VAR_INSN: break; case AbstractInsnNode.FIELD_INSN: FieldInsnNode fieldInsn = (FieldInsnNode) insn; if (fieldInsn.getOpcode() != PUTSTATIC) { // GETSTATIC, GETFIELD, PUTFIELD return false; } break; case AbstractInsnNode.IINC_INSN: return false; case AbstractInsnNode.INSN: if (unsafeInsnBytecodes.contains(insn.getOpcode())) { Log.debug(t.commonName() + ".<clinit>() is unsafe " + "because of bytecode " + insn.getOpcode()); return false; } break; case AbstractInsnNode.METHOD_INSN: MethodInsnNode methodInsn = (MethodInsnNode) insn; if (!ClassFilter.isMethodWhitelisted(Type.fromAsm(methodInsn.owner), methodInsn.name, methodInsn.desc)) { Log.debug(t.commonName() + ".<clinit>() is unsafe " + "because it invokes " + Type.fromAsm(methodInsn.owner).commonName() + "." + methodInsn.name); return false; } break; default: throw new Error("Unexpected bytecode " + insn); } } //Log.debug(t.commonName() + ".<clinit>() for " + t + " is safe"); return true; } return false; } catch (IOException e) { throw new Error(e); } }
From source file:jvstm.atomic.ProcessParNestAnnotations.java
License:Open Source License
protected static void processClassFile(File classFile) { alreadyProcessed = new ArrayList<String>(); callablesCreated = new HashMap<String, String>(); InputStream is = null;/*from ww w . j ava2 s . c om*/ try { // get an input stream to read the bytecode of the class is = new FileInputStream(classFile); ClassNode cn = new ClassNode(ASM4); ClassReader cr = new ClassReader(is); cr.accept(cn, 0); List<MethodNode> parNestedMethods = new ArrayList<MethodNode>(); MethodNode combinerMethod = null; MethodNode execMethod = null; List<MethodNode> staticMethodsToAdd = new ArrayList<MethodNode>(); boolean parallelSpawn = extendsParallelSpawn(cn); boolean unsafeSpawn = extendsUnsafeSpawn(cn); if (parallelSpawn || unsafeSpawn) { Iterator<MethodNode> methodIter = cn.methods.iterator(); while (methodIter.hasNext()) { MethodNode mn = methodIter.next(); if (mn.name.equals("exec") && execMethod == null) { execMethod = mn; continue; } if (mn.invisibleAnnotations == null) { continue; } for (AnnotationNode an : mn.invisibleAnnotations) { if (an.desc.equals(PAR_NEST.getDescriptor())) { // Ensure the method can be called from outside mn.access = (mn.access & ~ACC_PRIVATE) | ACC_PUBLIC; parNestedMethods.add(mn); String uniqueMethodName = createUniqueMethodName(mn.name); String callableClass; if (parallelSpawn) { callableClass = cn.name + "$nested$work$unit$" + uniqueMethodName; } else { callableClass = cn.name + "$unsafe$work$unit$" + uniqueMethodName; } callablesCreated.put(mn.name, callableClass); boolean readOnlyCallable = (an.values == null) ? false : (Boolean) an.values.get(1); generateCallable(classFile, cn.name, callableClass, mn, readOnlyCallable, unsafeSpawn); staticMethodsToAdd.add(generateStaticCallableCreation(cn, cn.name, callableClass, mn)); break; } else if (an.desc.equals(COMBINER.getDescriptor())) { if (combinerMethod != null) { throw new RuntimeException("Class: " + cn.name + " contains two @Combiner methods: " + combinerMethod.name + " and " + mn.name); } combinerMethod = mn; } } } // TODO Verify the @Combiner method // The return should be of the same type of the parameterization // of the ParallelSpawn for (MethodNode methodToAdd : staticMethodsToAdd) { cn.methods.add(methodToAdd); } if (alreadyProcessed.size() == 0) { throw new RuntimeException( "Class: " + cn.name + " must have at least one method annotated with @ParNested"); } if (combinerMethod == null) { throw new RuntimeException( "Class: " + cn.name + " must have one method annotated with @Combiner"); } List<Integer> localVariablesIdx = new ArrayList<Integer>(); int numberLocalVariables = 0; int listIndex = execMethod.maxLocals; execMethod.maxLocals++; InsnList preamble = new InsnList(); preamble.add(new TypeInsnNode(NEW, ARRAY_LIST.getInternalName())); preamble.add(new InsnNode(DUP)); preamble.add(new MethodInsnNode(INVOKESPECIAL, ARRAY_LIST.getInternalName(), "<init>", "()V")); preamble.add(new VarInsnNode(ASTORE, listIndex)); Iterator<AbstractInsnNode> execInstIter = execMethod.instructions.iterator(); while (execInstIter.hasNext()) { AbstractInsnNode instr = execInstIter.next(); // Look out for calls to methods if (instr.getOpcode() == INVOKEVIRTUAL || instr.getOpcode() == INVOKESPECIAL) { MethodInsnNode methodInstr = (MethodInsnNode) instr; // Is method being called annotated with @ParNested for (MethodNode parNestedMethod : parNestedMethods) { if (parNestedMethod.name.equals(methodInstr.name)) { numberLocalVariables++; } } } } for (int i = 0; i < numberLocalVariables; i++) { localVariablesIdx.add(i, execMethod.maxLocals); execMethod.maxLocals++; } int callablesManipulated = 0; execInstIter = execMethod.instructions.iterator(); while (execInstIter.hasNext()) { AbstractInsnNode instr = execInstIter.next(); // Look out for calls to methods if (instr.getOpcode() != INVOKEVIRTUAL && instr.getOpcode() != INVOKESPECIAL) { continue; } MethodInsnNode methodInstr = (MethodInsnNode) instr; // Is method being called annotated with @ParNested boolean isParNestedMethod = false; for (MethodNode parNestedMethod : parNestedMethods) { if (parNestedMethod.name.equals(methodInstr.name)) { isParNestedMethod = true; break; } } if (!isParNestedMethod) { continue; } // Let's change this call // If it was a call to: @ParNested public int add(int i1, // int i2) // add(foo, bar) -> add$static$callable$creator(this, foo, // bar) // the 'this' will be already in the right place in the // stack // because the method being called now is static whereas // previously // it was not methodInstr.setOpcode(INVOKESTATIC); methodInstr.name = methodInstr.name + "$static$callable$creator"; for (MethodNode staticCreated : staticMethodsToAdd) { if (staticCreated.name.equals(methodInstr.name)) { methodInstr.desc = staticCreated.desc; break; } } InsnList midterm = new InsnList(); // Store the callable instantiated in local variable midterm.add(new VarInsnNode(ASTORE, localVariablesIdx.get(callablesManipulated))); // Load the list midterm.add(new VarInsnNode(ALOAD, listIndex)); // Load the callable midterm.add(new VarInsnNode(ALOAD, localVariablesIdx.get(callablesManipulated))); // Add it to the list midterm.add(new MethodInsnNode(INVOKEVIRTUAL, ARRAY_LIST.getInternalName(), "add", "(Ljava/lang/Object;)Z")); // Pop the boolean that results from the add(Object) // May reuse a POP if the previous call had a return if (methodInstr.getNext().getOpcode() != POP) { midterm.add(new InsnNode(POP)); } // Add this set of instructions after the call to the // constrution of the callable execMethod.instructions.insert(methodInstr, midterm); callablesManipulated++; } // Insert the preamble in the start execMethod.instructions.insert(preamble); InsnList finish = new InsnList(); // Push 'this' for the call to the combiner method finish.add(new VarInsnNode(ALOAD, 0)); // Call the static method current() of jvstm.Transaction finish.add(new MethodInsnNode(INVOKESTATIC, TRANSACTION.getInternalName(), "current", "()Ljvstm/Transaction;")); // Load the callables list finish.add(new VarInsnNode(ALOAD, listIndex)); // Call the manage parnested method finish.add(new MethodInsnNode(INVOKEVIRTUAL, TRANSACTION.getInternalName(), "manageNestedParallelTxs", "(Ljava/util/List;)Ljava/util/List;")); // Call the combiner method finish.add(new MethodInsnNode(INVOKEVIRTUAL, cn.name, combinerMethod.name, combinerMethod.desc)); // Return what the combiner returns finish.add(new InsnNode(ARETURN)); // Remove the "return null" that's supposed to be at the end of // the exec method execInstIter = execMethod.instructions.iterator(); while (execInstIter.hasNext()) { AbstractInsnNode curNode = execInstIter.next(); if (!execInstIter.hasNext()) { // Insert the finish in the end execMethod.instructions.insert(curNode.getPrevious().getPrevious(), finish); execMethod.instructions.remove(curNode.getPrevious()); execMethod.instructions.remove(curNode); break; } } } ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cn.accept(cw); writeClassFile(classFile, cw.toByteArray()); } catch (IOException e) { throw new Error("Error processing class file", e); } finally { if (is != null) { try { is.close(); } catch (IOException e) { } } } }
From source file:kilim.analysis.BasicBlock.java
License:Open Source License
/** * Absorb as many instructions until the next label or the next transfer of * control instruction. In the first pass we may end up creating many many * BBs because there may be a lot of non-target labels (esp. when debug * information is available). The constraints are as follows: * 1. A transfer of control instruction must be the last instruction. It * may also be the first (and only) instruction * 2. A labeled instruction must be the first instruction in a BB. It * may optionally be the last (and only) instruction * 3. A pausable method is treated like a labeled instruction, and is * given a label if there isn't one already. Constraint 2 applies. *//*from www . j av a 2s .c om*/ @SuppressWarnings("unchecked") int initialize(int pos) { AbstractInsnNode ain; startPos = pos; BasicBlock bb; boolean endOfBB = false; boolean hasFollower = true; int size = flow.instructions.size(); for (; pos < size; pos++) { if (pos > startPos && flow.getLabelAt(pos) != null) { pos--; hasFollower = true; endOfBB = true; break; } ain = getInstruction(pos); int opcode = ain.getOpcode(); switch (opcode) { case ALOAD: case ILOAD: case LLOAD: case FLOAD: case DLOAD: usage.read(((VarInsnNode) ain).var); break; case ISTORE: case LSTORE: case FSTORE: case DSTORE: case ASTORE: usage.write(((VarInsnNode) ain).var); break; case IINC: int v = ((IincInsnNode) ain).var; usage.read(v); usage.write(v); break; case IFEQ: case IFNE: case IFLT: case IFGE: case IFGT: case IFLE: case IFNULL: case IFNONNULL: case IF_ICMPEQ: case IF_ICMPNE: case IF_ICMPLT: case IF_ICMPGE: case IF_ICMPGT: case IF_ICMPLE: case IF_ACMPEQ: case IF_ACMPNE: case JSR: case GOTO: bb = flow.getOrCreateBasicBlock(((JumpInsnNode) ain).label.getLabel()); if (opcode == JSR) { bb.setFlag(IS_SUBROUTINE); hasFollower = false; } addSuccessor(bb); if (opcode == GOTO) { hasFollower = false; } endOfBB = true; break; case RET: case IRETURN: case LRETURN: case FRETURN: case DRETURN: case ARETURN: case RETURN: case ATHROW: hasFollower = false; endOfBB = true; break; case TABLESWITCH: case LOOKUPSWITCH: LabelNode defaultLabel; List<LabelNode> otherLabels; if (opcode == TABLESWITCH) { defaultLabel = ((TableSwitchInsnNode) ain).dflt; otherLabels = ((TableSwitchInsnNode) ain).labels; } else { defaultLabel = ((LookupSwitchInsnNode) ain).dflt; otherLabels = ((LookupSwitchInsnNode) ain).labels; } for (Iterator<LabelNode> it = otherLabels.iterator(); it.hasNext();) { addSuccessor(flow.getOrCreateBasicBlock(((LabelNode) it.next()).getLabel())); } addSuccessor(flow.getOrCreateBasicBlock(defaultLabel.getLabel())); endOfBB = true; hasFollower = false; break; case INVOKEVIRTUAL: case INVOKESTATIC: case INVOKEINTERFACE: case INVOKEDYNAMIC: // TODO this is new and mysterious case INVOKESPECIAL: if (flow.isPausableMethodInsn((MethodInsnNode) ain)) { if (pos == startPos) { setFlag(PAUSABLE); } else { bb = flow.getOrCreateBasicBlock(flow.getOrCreateLabelAtPos(pos)); bb.setFlag(PAUSABLE); addSuccessor(bb); pos--; // don't consume this instruction hasFollower = true; endOfBB = true; } } break; default: if (opcode >= 26 && opcode <= 45) throw new IllegalStateException("instruction variants not expected here"); break; } if (endOfBB) break; } endPos = pos; if (hasFollower && (pos + 1) < flow.instructions.size()) { // add the following basic block as a successor Label l = flow.getOrCreateLabelAtPos(pos + 1); bb = flow.getOrCreateBasicBlock(l); addFollower(bb); } return pos; }
From source file:kilim.analysis.BasicBlock.java
License:Open Source License
int lastInstruction() { AbstractInsnNode ainode = getInstruction(endPos); return ainode.getOpcode(); }
From source file:kilim.analysis.BasicBlock.java
License:Open Source License
void interpret() { Value v, v1, v2, v3, v4;//from w w w. j a v a 2s . co m 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; } }
From source file:kilim.analysis.BasicBlock.java
License:Open Source License
@SuppressWarnings("unchecked") static ArrayList<BasicBlock> dupCopyContents(boolean deepCopy, BasicBlock targetBB, BasicBlock returnToBB, HashMap<BasicBlock, BasicBlock> bbCopyMap, HashMap<Label, LabelNode> labelCopyMap) throws KilimException { ArrayList<BasicBlock> newBBs = new ArrayList<BasicBlock>(targetBB.getSubBlocks().size()); for (BasicBlock orig : targetBB.getSubBlocks()) { BasicBlock dup = bbCopyMap.get(orig); dup.flags = orig.flags;// w ww.j a va2 s. c o m dup.caughtExceptionType = orig.caughtExceptionType; dup.startPos = orig.startPos; dup.endPos = orig.endPos; dup.flow = orig.flow; dup.numPredecessors = orig.numPredecessors; dup.startFrame = null; dup.usage = orig.usage.copy(); dup.handlers = orig.handlers; if (orig.follower != null) { dup.follower = bbCopyMap.get(orig.follower); if (dup.follower == null) { assert dup.lastInstruction() == RET; } } dup.successors = new ArrayList<BasicBlock>(orig.successors.size()); if (orig.lastInstruction() == RET) { dup.addSuccessor(returnToBB); } else { for (BasicBlock s : orig.successors) { BasicBlock b = bbCopyMap.get(s); dup.addSuccessor(b); } } if (deepCopy) { MethodFlow flow = targetBB.flow; InsnList instructions = flow.instructions; // copy instructions dup.startLabel = labelCopyMap.get(orig.startLabel).getLabel(); dup.startPos = instructions.size(); dup.endPos = dup.startPos + (orig.endPos - orig.startPos); // Note: last instruction (@endPos) isn't copied in the loop. // If it has labels, a new instruction is generated; either // way the last instruction is appended separately. int newPos = instructions.size(); int end = orig.endPos; // create new labels and instructions for (int i = orig.startPos; i <= end; i++, newPos++) { Label l = flow.getLabelAt(i); if (l != null) { l = labelCopyMap.get(l).getLabel(); assert l != null; flow.setLabel(newPos, l); } if (i != end) { // last insn gets special treatment instructions.add(instructions.get(i)); } } AbstractInsnNode lastInsn = (AbstractInsnNode) instructions.get(orig.endPos); LabelNode dupLabel; int opcode = lastInsn.getOpcode(); if (lastInsn instanceof JumpInsnNode) { JumpInsnNode jin = (JumpInsnNode) lastInsn; if (lastInsn.getOpcode() != JSR) { dupLabel = labelCopyMap.get(jin.label); assert dupLabel != null; lastInsn = new JumpInsnNode(lastInsn.getOpcode(), dupLabel); } } else if (opcode == TABLESWITCH) { TableSwitchInsnNode tsin = (TableSwitchInsnNode) lastInsn; LabelNode[] labels = new LabelNode[tsin.labels.size()]; for (int i = 0; i < labels.length; i++) { dupLabel = labelCopyMap.get(tsin.labels.get(i)); assert dupLabel != null; labels[i] = dupLabel; } dupLabel = labelCopyMap.get(tsin.dflt); assert dupLabel != null; lastInsn = new TableSwitchInsnNode(tsin.min, tsin.max, dupLabel, labels); } else if (opcode == LOOKUPSWITCH) { LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) lastInsn; LabelNode[] labels = new LabelNode[lsin.labels.size()]; for (int i = 0; i < labels.length; i++) { dupLabel = labelCopyMap.get(lsin.labels.get(i)); assert dupLabel != null; labels[i] = dupLabel; } dupLabel = labelCopyMap.get(lsin.dflt); assert dupLabel != null; int[] keys = new int[lsin.keys.size()]; for (int i = 0; i < keys.length; i++) { keys[i] = (Integer) lsin.keys.get(i); } lastInsn = new LookupSwitchInsnNode(dupLabel, keys, labels); } instructions.add(lastInsn); // new handlers dup.handlers = new ArrayList<Handler>(orig.handlers.size()); if (orig.handlers.size() > 0) { for (Handler oh : orig.handlers) { Handler h = new Handler(dup.startPos + (oh.from - orig.startPos), dup.endPos + (oh.to - orig.endPos), oh.type, oh.catchBB); dup.handlers.add(h); } } } newBBs.add(dup); } return newBBs; }
From source file:kilim.analysis.BasicBlock.java
License:Open Source License
public boolean isGetCurrentTask() { AbstractInsnNode ain = getInstruction(startPos); if (ain.getOpcode() == INVOKESTATIC) { MethodInsnNode min = (MethodInsnNode) ain; return min.owner.equals(TASK_CLASS) && min.name.equals("getCurrentTask"); }// w w w. j a v a2s . c o m return false; }
From source file:name.martingeisse.minimal.compiler.Compiler.java
License:Open Source License
/** * Compiles a {@link MethodNode} to MCode. * // w w w . ja va2 s .co m * @param methodNode the method node to compile * @return the compiled code */ public ImmutableList<MCodeEntry> compile(final MethodNode methodNode) { for (int i = 0; i < methodNode.instructions.size(); i++) { final AbstractInsnNode instruction = methodNode.instructions.get(i); if (instruction instanceof LineNumberNode) { // ignored } else if (instruction instanceof FrameNode) { // this could be useful in the future } else if (instruction instanceof LabelNode) { label(((LabelNode) instruction).getLabel()); } else if (instruction instanceof InsnNode) { switch (instruction.getOpcode()) { case Opcodes.ICONST_M1: iconst(-1); break; case Opcodes.ICONST_0: iconst(0); break; case Opcodes.ICONST_1: iconst(1); break; case Opcodes.ICONST_2: iconst(2); break; case Opcodes.ICONST_3: iconst(3); break; case Opcodes.ICONST_4: iconst(4); break; case Opcodes.ICONST_5: iconst(5); break; default: unsupported(instruction); break; } } else if (instruction instanceof VarInsnNode) { final VarInsnNode varInsnNode = (VarInsnNode) instruction; switch (varInsnNode.getOpcode()) { case Opcodes.ILOAD: iload(varInsnNode.var); break; case Opcodes.ISTORE: istore(varInsnNode.var); break; default: unsupported(instruction); break; } } else if (instruction instanceof IincInsnNode) { final IincInsnNode iincInsnNode = (IincInsnNode) instruction; iinc(iincInsnNode.var, iincInsnNode.incr); } else if (instruction instanceof JumpInsnNode) { final JumpInsnNode jumpInsnNode = (JumpInsnNode) instruction; switch (jumpInsnNode.getOpcode()) { case Opcodes.IFEQ: case Opcodes.IFNE: case Opcodes.IFLT: case Opcodes.IFGE: case Opcodes.IFGT: case Opcodes.IFLE: branch1(jumpInsnNode.label.getLabel(), jumpInsnNode.getOpcode()); 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: branch2(jumpInsnNode.label.getLabel(), jumpInsnNode.getOpcode()); break; case Opcodes.IFNULL: case Opcodes.IFNONNULL: // unsupported: one-argument reference comparison operator unsupported(instruction); break; case Opcodes.IF_ACMPEQ: case Opcodes.IF_ACMPNE: // unsupported: two-argument reference comparison operator unsupported(instruction); break; case Opcodes.GOTO: jump(jumpInsnNode.label.getLabel()); break; case Opcodes.JSR: jsr(jumpInsnNode.label.getLabel()); break; default: unsupported(instruction); break; } } else if (instruction instanceof IntInsnNode) { final IntInsnNode intInsnNode = (IntInsnNode) instruction; if (instruction.getOpcode() == Opcodes.BIPUSH || instruction.getOpcode() == Opcodes.SIPUSH) { iconst(intInsnNode.operand); } else { // NEWARRAY unsupported(instruction); } } else if (instruction instanceof MethodInsnNode) { final MethodInsnNode methodInsnNode = (MethodInsnNode) instruction; if (methodInsnNode.getOpcode() == Opcodes.INVOKESTATIC) { if (methodInsnNode.owner.replace('/', '.').equals(Native.class.getName())) { nativeCall(methodInsnNode.name, methodInsnNode.desc); } else { unsupported(instruction); } } else { unsupported(instruction); } } else { unsupported(instruction); } } return builder.build(); }