Example usage for org.objectweb.asm.tree AbstractInsnNode getOpcode

List of usage examples for org.objectweb.asm.tree AbstractInsnNode getOpcode

Introduction

In this page you can find the example usage for org.objectweb.asm.tree AbstractInsnNode getOpcode.

Prototype

public int getOpcode() 

Source Link

Document

Returns the opcode of this instruction.

Usage

From source file:pku.sei.checkedcoverage.tracer.instrumentation.TracingMethodInstrumenter.java

License:Creative Commons License

private void transformTypeInsn(final TypeInsnNode insn) {
    if (insn.getOpcode() == ANEWARRAY) {
        // after the ANEWARRAY instruction, insert code that traces the
        // object identifier of the newly created object/array
        final int newObjectIdSeqIndex = this.tracer.newLongTraceSequence();
        registerInstruction(new TypeInstruction(this.readMethod, insn.getOpcode(), this.currentLine, insn.desc,
                newObjectIdSeqIndex), InstructionType.UNSAFE);
        this.instructionIterator.add(new InsnNode(DUP));
        this.instructionIterator.add(new VarInsnNode(ALOAD, this.tracerLocalVarIndex));
        this.instructionIterator.add(new InsnNode(SWAP));
        this.instructionIterator.add(getIntConstInsn(newObjectIdSeqIndex));
        this.instructionIterator.add(new MethodInsnNode(INVOKEINTERFACE,
                Type.getInternalName(ThreadTracer.class), "traceObject", "(Ljava/lang/Object;I)V"));
    } else if (insn.getOpcode() == NEW) {
        // after a NEW, we store the sequence number in the ThreadTracer object.
        // after the constructor has been called (which is guaranteed), its
        // id is written to the stored sequence number
        final int newObjectIdSeqIndex = this.tracer.newLongTraceSequence();
        final AbstractInstruction instruction = new TypeInstruction(this.readMethod, insn.getOpcode(),
                this.currentLine, insn.desc, newObjectIdSeqIndex);
        if (!this.instructionIterator.hasNext()) {
            if (this.tracer.debug)
                Transformer.printMethod(System.err, this.methodNode);
            throw new TracerException("Bytecode of method " + this.classNode.name + "." + this.methodNode.name
                    + " has unsupported form. Maybe it was compiled for JRE < 1.5?");
        } else if (this.instructionIterator.next().getOpcode() != DUP) {
            this.instructionIterator.previous();
            AbstractInsnNode dup_x1 = this.instructionIterator.next();
            AbstractInsnNode swap = null;
            AbstractInsnNode init = null;

            boolean matches = false;
            if (dup_x1.getOpcode() == DUP_X1 && this.instructionIterator.hasNext()) {
                swap = this.instructionIterator.next();
                if (swap.getOpcode() == SWAP && this.instructionIterator.hasNext()) {
                    init = this.instructionIterator.next();
                    if (init.getOpcode() == INVOKESPECIAL) {
                        MethodInsnNode mtdInvokation = (MethodInsnNode) init;
                        Type[] args = Type.getArgumentTypes(mtdInvokation.desc);
                        if ("<init>".equals(mtdInvokation.name) && args.length == 1
                                && args[0].getSort() == Type.OBJECT) {
                            matches = true;
                        }/*from   w  w  w .ja v a  2  s. com*/
                    }
                }
            }

            if (matches) {
                // add another DUP_X1 after the existing one
                this.instructionIterator.previous();
                this.instructionIterator.previous();
                this.instructionIterator.add(new InsnNode(DUP_X1));
                //                    if (this.tracer.debug) {
                //                        System.err.println("Added DUP_X1 at position " + this.instructionIterator.previousIndex() + "!");
                //                        Transformer.printMethod(System.err, this.methodNode);
                //                    }
                this.instructionIterator.next(); // next instruction visited would be the <init> call
            } else {
                if (this.tracer.debug)
                    Transformer.printMethod(System.err, this.methodNode);
                throw new TracerException("Bytecode of method " + this.classNode.name + "."
                        + this.methodNode.name + " has unsupported form. Maybe it was compiled for JRE < 1.5?");
            }
        } else {
            this.instructionIterator.previous();
            this.instructionIterator.add(new InsnNode(DUP));
        }
        ++this.outstandingInitializations;
        // modified code of registerInstruction():
        this.readMethod.addInstruction(instruction);
        this.instructionIterator.previous();
        this.instructionIterator.add(new VarInsnNode(ALOAD, this.tracerLocalVarIndex));
        this.instructionIterator.add(getIntConstInsn(instruction.getIndex()));
        this.instructionIterator.add(getIntConstInsn(newObjectIdSeqIndex));
        this.instructionIterator.add(new MethodInsnNode(INVOKEINTERFACE,
                Type.getInternalName(ThreadTracer.class), "objectAllocated", "(II)V"));
        this.instructionIterator.next();
        ++TracingMethodInstrumenter.statsInstructions;
    } else {
        registerInstruction(
                new TypeInstruction(this.readMethod, insn.getOpcode(), this.currentLine, insn.desc, -1),
                InstructionType.UNSAFE);
    }
}

From source file:pl.clareo.coroutines.core.MethodTransformer.java

License:Apache License

@SuppressWarnings("unchecked")
MethodNode transform(String coroutineName, boolean generateDebugCode) {
    MethodNode transformedMethod = new MethodNode();
    transformedMethod.access = ACC_PUBLIC | ACC_FINAL | (method.access & ACC_STATIC);
    transformedMethod.name = coroutineName;
    transformedMethod.desc = COROUTINE_METHOD_DESCRIPTOR;
    transformedMethod.exceptions = method.exceptions;
    final InsnList newCode = transformedMethod.instructions;
    Analyzer analyzer = new Analyzer(new BasicInterpreter() {

        @Override//from  w  ww .  jav  a2  s .c  o  m
        public Value binaryOperation(AbstractInsnNode insn, Value value1, Value value2)
                throws AnalyzerException {
            if (insn.getOpcode() == AALOAD) {
                return new BasicValue(((BasicValue) value1).getType().getElementType());
            }
            return super.binaryOperation(insn, value1, value2);
        };

        @Override
        public Value merge(Value v, Value w) {
            if (v == NULL_VALUE) {
                BasicValue w1 = (BasicValue) w;
                if (w1.isReference()) {
                    return w1;
                }
            }
            if (w == NULL_VALUE) {
                BasicValue v1 = (BasicValue) v;
                if (v1.isReference())
                    return v1;
            }
            if (!v.equals(w)) {
                BasicValue v1 = (BasicValue) v;
                BasicValue w1 = (BasicValue) w;
                if (v1.isReference() & w1.isReference()) {
                    Class<?> c1;
                    Class<?> c2;
                    try {
                        c1 = MethodTransformer.getClass(v1);
                        c2 = MethodTransformer.getClass(w1);
                    } catch (ClassNotFoundException e) {
                        throw new CoroutineGenerationException(
                                "It was needed to load a class during transformation process but loading unexpectedly failed",
                                e);
                    }
                    if (c1.isAssignableFrom(c2)) {
                        return v;
                    }
                    if (c2.isAssignableFrom(c1)) {
                        return w;
                    }
                }
            } else {
                return v;
            }
            return BasicValue.UNINITIALIZED_VALUE;
        }

        @Override
        public Value newValue(Type type) {
            if (type != null) {
                int typeSort = type.getSort();
                switch (typeSort) {
                case Type.VOID:
                    return NULL_VALUE;
                case Type.BOOLEAN:
                case Type.CHAR:
                case Type.BYTE:
                case Type.SHORT:
                case Type.INT:
                    return BasicValue.INT_VALUE;
                case Type.FLOAT:
                    return BasicValue.FLOAT_VALUE;
                case Type.LONG:
                    return BasicValue.LONG_VALUE;
                case Type.DOUBLE:
                    return BasicValue.DOUBLE_VALUE;
                case Type.ARRAY:
                case Type.OBJECT:
                    if (type.getInternalName().equals("null")) {
                        return NULL_VALUE;
                    }
                    return new BasicValue(type);
                default:
                    throw new Error("Internal error");
                }
            }
            return BasicValue.UNINITIALIZED_VALUE;
        }
    });
    Frame[] frames;
    try {
        frames = analyzer.analyze(methodOwner, method);
    } catch (AnalyzerException e) {
        throw new CoroutineGenerationException(e);
    }
    InsnList code = method.instructions;
    final List<Integer> yields = new ArrayList<Integer>(8);
    /*
     * Copy instructions patching variable indexes and frames, remember
     * yield indexes
     */
    int ic = 0;
    Iterator<AbstractInsnNode> i = code.iterator();
    while (i.hasNext()) {
        AbstractInsnNode insn = i.next();
        switch (insn.getType()) {
        case AbstractInsnNode.FRAME:
            FrameNode frame = (FrameNode) insn.clone(labelsMap);
            // update values
            if (frame.type == F_FULL) {
                if (isStatic) {
                    frame.local.addAll(0, argsStackMapList);
                } else {
                    frame.local.addAll(1, argsStackMapList);
                }
            }
            newCode.add(frame);
            break;
        case AbstractInsnNode.IINC_INSN:
            IincInsnNode iinc = (IincInsnNode) insn.clone(labelsMap);
            iinc.var += variableIndexOffset;
            newCode.add(iinc);
            break;
        case AbstractInsnNode.INSN:
            switch (insn.getOpcode()) {
            case DRETURN:
            case FRETURN:
            case IRETURN:
            case LRETURN:
            case ARETURN:
            case RETURN:
                newCode.add(new InsnNode(POP));
                newCode.add(throwex("java/util/NoSuchElementException"));
                break;
            default:
                newCode.add(insn.clone(labelsMap));
            }
            break;
        case AbstractInsnNode.JUMP_INSN:
            if (insn.getOpcode() == JSR) {
                throw new CoroutineGenerationException("<jsr> not allowed");
            }
            JumpInsnNode jump = (JumpInsnNode) insn;
            LabelNode target = jump.label;
            if (!labelsMap.containsKey(target)) {
                labelsMap.put(target, new LabelNode());
            }
            newCode.add(jump.clone(labelsMap));
            break;
        case AbstractInsnNode.LABEL:
            if (!labelsMap.containsKey(insn)) {
                labelsMap.put((LabelNode) insn, new LabelNode());
            }
            newCode.add(insn.clone(labelsMap));
            break;
        case AbstractInsnNode.METHOD_INSN:
            if (insn.getOpcode() == INVOKESTATIC) {
                MethodInsnNode method = (MethodInsnNode) insn;
                if (method.owner.equals(COROUTINES_NAME)) {
                    String methodName = method.name;
                    if (methodName.equals("_")) {
                        /*
                         * a call to artificial CoIterator, since it is
                         * not needed after instrumentation we replace
                         * it with null. This null will be popped by
                         * corresponding ARETURN. Stack is not changed
                         */
                        newCode.add(new InsnNode(ACONST_NULL));
                        break;
                    }
                    if (methodName.equals("yield")) {
                        /*
                         * a call to yield - core of coroutine
                         * processing
                         */
                        yields.add(ic);
                    }
                }
            }
            newCode.add(insn.clone(labelsMap));
            break;
        case AbstractInsnNode.VAR_INSN:
            if (insn.getOpcode() == RET) {
                throw new CoroutineGenerationException("<ret> not allowed");
            }
            VarInsnNode var = (VarInsnNode) insn.clone(labelsMap);
            if (var.var != 0 || isStatic) {
                var.var += variableIndexOffset;
            }
            newCode.add(var);
            break;
        default:
            newCode.add(insn.clone(labelsMap));
            break;
        }
        ic += 1;
    }
    /*
     * patch yields in transformed code
     */
    final List<LabelNode> gotos = new ArrayList<LabelNode>(9);
    final Set<TryCatchBlockNode> patchedTryCatchBlocks = new HashSet<TryCatchBlockNode>();
    int yieldIndex = 0;
    i = newCode.iterator();
    while (i.hasNext()) {
        AbstractInsnNode insn = i.next();
        /*
         * track locals
         */
        int insnType = insn.getType();
        if (insnType == AbstractInsnNode.VAR_INSN) {
            int opcode = insn.getOpcode();
            if (opcode == ASTORE || opcode == DSTORE || opcode == LSTORE || opcode == ISTORE
                    || opcode == FSTORE) {
                int varIndex = ((VarInsnNode) insn).var - variableIndexOffset;
                finals[varIndex] = false;
            }
            continue;
        }
        /*
         * track line numbers
         */
        if (insnType == AbstractInsnNode.LINE) {
            lineNumber = ((LineNumberNode) insn).line;
            continue;
        }
        if (insnType != AbstractInsnNode.METHOD_INSN) {
            continue;
        }
        MethodInsnNode method = (MethodInsnNode) insn;
        if (!method.owner.equals(COROUTINES_NAME) || !method.name.equals("yield")) {
            continue;
        }
        InsnList yieldCode = new InsnList();
        int index = yields.get(yieldIndex);
        Frame f = frames[index];
        /*
         * a) operand on the top of stack is passed to the caller, we will
         * save it in 'in' parameter OR there is nothing to be passed to the
         * caller in case of yield() overload
         */
        boolean yieldWithArgument = Type.getArgumentTypes(method.desc).length != 0;
        boolean nonemptyStack;
        Type[] stackContents = null;
        int stackTop = 0;
        if (yieldWithArgument) {
            yieldCode.add(input(getStackTop(f)));
            nonemptyStack = f.getStackSize() > 1;
            stackTop = 1;
        } else {
            nonemptyStack = f.getStackSize() > 0;
        }
        /*
         * b) save remaining stack
         */
        if (nonemptyStack) {
            stackContents = getStackContents(f);
            // sanitize stack
            for (Type t : stackContents) {
                if (t == null) {
                    throw new CoroutineGenerationException(
                            "It is not possible to yield with uninitialized memory on the stack. Probably you use construct such as: new A(..,yield,..). Please move this yield call out of constructor");
                }
            }
            yieldCode.add(savestack(frame, stackContents, stackTop));
        }
        /*
         * c) save locals and state
         */
        Type[] locals = getLocals(f);
        yieldCode.add(saveLocals(locals));
        yieldCode.add(new VarInsnNode(ALOAD, frame));
        yieldCode.add(makeInt(++yieldIndex));
        yieldCode.add(new MethodInsnNode(INVOKEVIRTUAL, FRAME_NAME, "setState", "(I)V"));
        /*
         * d) jump to exit - in debug mode save line number
         */
        if (generateDebugCode) {
            yieldCode.add(new VarInsnNode(ALOAD, frame));
            yieldCode.add(makeInt(lineNumber));
            yieldCode.add(new MethodInsnNode(INVOKEVIRTUAL, FRAME_NAME, "setLineOfCode", "(I)V"));
        }
        yieldCode.add(new JumpInsnNode(GOTO, yieldLabel));
        /*
         * e) fix jump from switch statement
         */
        LabelNode jump = new LabelNode();
        gotos.add(jump);
        yieldCode.add(jump);
        yieldCode.add(emitCleanFrame());
        /*
         * f) check if exit condition occurs, load locals, restore stack and
         * stack map
         */
        yieldCode.add(new VarInsnNode(ALOAD, frame));
        yieldCode.add(new MethodInsnNode(INVOKEVIRTUAL, FRAME_NAME, "isCoroutineClosed", "()Z"));
        LabelNode continueHere = new LabelNode();
        yieldCode.add(new JumpInsnNode(IFEQ, continueHere));
        yieldCode.add(throwex(COROUTINE_EXIT_EXCEPTION));
        yieldCode.add(continueHere);
        yieldCode.add(new FrameNode(F_SAME, 0, EMPTY_LOCALS, 0, EMPTY_STACK));
        /*
         * find previous frame node, load locals then emit new frame node
         * and load rest
         */
        FrameNode prevFrame = findPreviousFrame(code.get(index));
        Type[] prevLocals;
        if (prevFrame != null) {
            Frame oldFrame = frames[code.indexOf(prevFrame)];
            prevLocals = getLocals(oldFrame);
        } else {
            prevLocals = getLocals(frames[0]);
        }
        yieldCode.add(restoreLocals(prevLocals));
        FrameNode frameNode = mergeFrames(getFrameTypes(prevLocals), null);
        if (frameNode.type != F_SAME) {
            // bug fix - when no locals are restored and the stack is empty
            // two frames are collapsed
            yieldCode.add(frameNode);
        }
        if (nonemptyStack) {
            yieldCode.add(loadstack(frame, stackContents, stackTop));
        }
        // restore temp locals in scope
        yieldCode.add(restoreLocals(diff(locals, prevLocals)));
        /*
         * push "sent" value
         */
        yieldCode.add(new VarInsnNode(ALOAD, out));
        newCode.insertBefore(method, yieldCode);
        /*
         * patch try catch blocks
         */
        List<TryCatchBlockNode> tryCatchBlocks = analyzer.getHandlers(index);
        if (tryCatchBlocks != null) {
            for (TryCatchBlockNode tryCatchBlock : tryCatchBlocks) {
                if (!patchedTryCatchBlocks.contains(tryCatchBlock)) {
                    LabelNode handler = tryCatchBlock.handler;
                    InsnList handlerPatch = new InsnList();
                    String exceptionType = tryCatchBlock.type == null ? "java/lang/Throwable"
                            : tryCatchBlock.type;
                    FrameNode catchFrame = emitCatchFrame(exceptionType);
                    handlerPatch.add(catchFrame);
                    Type[] ls = getLocals(frames[code.indexOf(handler)]);
                    handlerPatch.add(restoreLocals(ls));
                    handlerPatch.add(
                            mergeFrames(getFrameTypes(ls), new Type[] { Type.getObjectType(exceptionType) }));
                    patchedTryCatchBlocks.add(tryCatchBlock);
                    AbstractInsnNode newHandler = labelsMap.get(handler);
                    // remove "real" frame since it is not needed now
                    newCode.remove(findNextFrame(newHandler));
                    newCode.insert(newHandler, handlerPatch);
                }
            }
        }
        newCode.remove(method);
    }
    /*
     * copy local variables (wath out for indices change) and try catch
     * blocks to new method (clone)
     */
    List<TryCatchBlockNode> tryCatchBlocks = method.tryCatchBlocks;
    if (!tryCatchBlocks.isEmpty()) {
        transformedMethod.tryCatchBlocks = new ArrayList<TryCatchBlockNode>(tryCatchBlocks.size());
        for (TryCatchBlockNode tryCatchBlock : tryCatchBlocks) {
            transformedMethod.tryCatchBlocks.add(
                    new TryCatchBlockNode(labelsMap.get(tryCatchBlock.start), labelsMap.get(tryCatchBlock.end),
                            labelsMap.get(tryCatchBlock.handler), tryCatchBlock.type));
        }
    }
    if (method.localVariables != null) {
        List<LocalVariableNode> localVariables = method.localVariables;
        List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>(localVariables.size());
        for (LocalVariableNode localVariable : localVariables) {
            int newIndex = localVariable.index;
            if (newIndex != 0 || isStatic) {
                newIndex += variableIndexOffset;
            }
            newLocalVariables
                    .add(new LocalVariableNode(localVariable.name, localVariable.desc, localVariable.signature,
                            labelsMap.get(localVariable.start), labelsMap.get(localVariable.end), newIndex));
        }
        transformedMethod.localVariables = newLocalVariables;
    }
    newCode.insert(codeBefore(gotos));
    newCode.add(codeAfter());
    return transformedMethod;
}

From source file:pxb.android.dex2jar.optimize.B.java

License:Apache License

/**
 * <pre>//from   ww  w. java  2s . co  m
 * BEFORE:
 *     LDC Ljavax/servlet/GenericServlet;.class
 *     ASTORE 1
 *     LDC "/javax/servlet/LocalStrings.properties"
 *     ASTORE 2
 *     ALOAD 1
 *     ALOAD 2
 *     INVOKEVIRTUAL Ljava/lang/Class;.getResourceAsStream (Ljava/lang/String;)Ljava/io/InputStream;
 *     ASTORE 1
 *     NEW Ljava/util/PropertyResourceBundle;
 *     DUP
 *     ALOAD 1
 *     INVOKESPECIAL Ljava/util/PropertyResourceBundle;.&lt;init> (Ljava/io/InputStream;)V
 *     ASTORE 0
 *     ALOAD 0
 *     PUTSTATIC Ljavax/servlet/GenericServlet;.lStrings : Ljava/util/ResourceBundle;
 * </pre>
 * 
 * <pre>
 * AFTER:
 *     LDC Ljavax/servlet/GenericServlet;.class
 *     LDC "/javax/servlet/LocalStrings.properties"
 *     INVOKEVIRTUAL Ljava/lang/Class;.getResourceAsStream (Ljava/lang/String;)Ljava/io/InputStream;
 *     ASTORE 1
 *     NEW Ljava/util/PropertyResourceBundle;
 *     DUP
 *     ALOAD 1
 *     INVOKESPECIAL Ljava/util/PropertyResourceBundle;.&lt;init> (Ljava/io/InputStream;)V
 *     ASTORE 0
 *     ALOAD 0
 *     PUTSTATIC Ljavax/servlet/GenericServlet;.lStrings : Ljava/util/ResourceBundle;
 * </pre>
 * 
 * @param block
 */
private void doLdc(Block block) {
    Map<Integer, LdcInsnNode> map = new HashMap<Integer, LdcInsnNode>();
    AbstractInsnNode p = block.first.getNext();
    while (p != null && p != block.last) {
        if (p.getOpcode() == Opcodes.LDC) {
            AbstractInsnNode q = p.getNext();
            if (isWrite(q)) {
                Integer var = var(q);
                if (block.out.get(var) == null || block.out.get(var) != q) {
                    map.put(var, (LdcInsnNode) p);
                    insnList.remove(q); // remove store
                    q = p.getPrevious();
                    insnList.remove(p); // remove ldc
                    p = q;
                }
            }
        } else if (isRead(p)) {
            Integer var = var(p);
            if (block.out.get(var) == null || block.out.get(var) != p) {
                LdcInsnNode ldc = map.get(var);
                if (ldc != null) {
                    AbstractInsnNode _ldc_copy = ldc.clone(null);
                    insnList.insert(p, _ldc_copy);
                    insnList.remove(p);
                    p = _ldc_copy;
                }
            }
        } else if (isWrite(p)) {
            Integer var = var(p);
            map.remove(var);
        }
        p = p.getNext();
    }
}

From source file:pxb.android.dex2jar.optimize.B.java

License:Apache License

/**
 * //from  ww  w. j  a  v a2s  .  c o m
 * 
 * NEWINVOKESPECIAL??
 * 
 * <pre>
 * BEFORE:
 *     NEW Ljava/util/PropertyResourceBundle;
 *     ASTORE 0
 *     LDC Ljavax/servlet/GenericServlet;.class
 *     ASTORE 1
 *     LDC "/javax/servlet/LocalStrings.properties"
 *     ASTORE 2
 *     ALOAD 1
 *     ALOAD 2
 *     INVOKEVIRTUAL Ljava/lang/Class;.getResourceAsStream (Ljava/lang/String;)Ljava/io/InputStream;
 *     ASTORE 1
 *     ALOAD 0
 *     ALOAD 1
 *     INVOKESPECIAL Ljava/util/PropertyResourceBundle;.&lt;init> (Ljava/io/InputStream;)V
 *     ALOAD 0
 *     PUTSTATIC Ljavax/servlet/GenericServlet;.lStrings : Ljava/util/ResourceBundle;
 * </pre>
 * 
 * 
 * <pre>
 * AFTER:
 *     LDC Ljavax/servlet/GenericServlet;.class
 *     ASTORE 1
 *     LDC "/javax/servlet/LocalStrings.properties"
 *     ASTORE 2
 *     ALOAD 1
 *     ALOAD 2
 *     INVOKEVIRTUAL Ljava/lang/Class;.getResourceAsStream (Ljava/lang/String;)Ljava/io/InputStream;
 *     ASTORE 1
 *     NEW Ljava/util/PropertyResourceBundle;
 *     DUP
 *     ALOAD 1
 *     INVOKESPECIAL Ljava/util/PropertyResourceBundle;.&lt;init> (Ljava/io/InputStream;)V
 *     ASTORE 0
 *     ALOAD 0
 *     PUTSTATIC Ljavax/servlet/GenericServlet;.lStrings : Ljava/util/ResourceBundle;
 * </pre>
 * 
 * @param block
 */
private void doNew(Block block) {
    Map<String, AbstractInsnNode> map = new HashMap<String, AbstractInsnNode>();
    AbstractInsnNode p = block.first.getNext();
    while (p != null && p != block.last) {
        switch (p.getOpcode()) {
        case Opcodes.NEW: {
            AbstractInsnNode store = p.getNext();
            if (store instanceof VarInsnNode) {
                map.put(((TypeInsnNode) p).desc + var(store), p);
                p = store.getNext();
            } else {
                p = store;
            }
            break;
        }
        case Opcodes.INVOKESPECIAL: {
            MethodInsnNode m = (MethodInsnNode) p;
            p = p.getNext();
            if (m.name.equals("<init>")) {
                int length = Type.getArgumentTypes(m.desc).length;
                AbstractInsnNode q = m.getPrevious();
                while (length-- > 0) {
                    q = q.getPrevious();
                }
                AbstractInsnNode _new = map.remove(m.owner + var(q));
                if (_new != null) {
                    AbstractInsnNode _store = _new.getNext();
                    insnList.remove(_new);// remove new
                    insnList.remove(_store); // remove store
                    insnList.insertBefore(q, _new);
                    insnList.insert(_new, new InsnNode(DUP));
                    insnList.remove(q);
                    insnList.insert(m, _store);
                }
            }
            break;
        }
        default:
            p = p.getNext();
        }
    }
}

From source file:pxb.android.dex2jar.optimize.B.java

License:Apache License

private void linkBlocks() {
    for (int i = 0; i < blocks.size(); i++) {
        Block block = blocks.get(i);//  ww w  . ja  va 2s .c o  m
        AbstractInsnNode node = block.last.getPrevious();
        switch (node.getType()) {
        case AbstractInsnNode.JUMP_INSN: {
            JumpInsnNode jump = (JumpInsnNode) node;
            link(block, blockMaps.get(jump.label.getLabel()));
            if (jump.getOpcode() != GOTO) {
                link(block, blocks.get(i + 1));
            }
            break;
        }
        case AbstractInsnNode.LOOKUPSWITCH_INSN: {
            LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) node;
            link(block, blockMaps.get(lsin.dflt.getLabel()));
            for (Object l : lsin.labels) {
                LabelNode label = (LabelNode) l;
                link(block, blockMaps.get(label.getLabel()));
            }
            break;
        }
        case AbstractInsnNode.TABLESWITCH_INSN: {
            TableSwitchInsnNode tsin = (TableSwitchInsnNode) node;
            link(block, blockMaps.get(tsin.dflt.getLabel()));
            for (Object l : tsin.labels) {
                LabelNode label = (LabelNode) l;
                link(block, blockMaps.get(label.getLabel()));
            }
            break;
        }
        default: {
            int insnOpcode = node.getOpcode();
            if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
                link(block, blocks.get(i + 1));
            }
            break;
        }
        }
    }
}

From source file:pxb.android.dex2jar.optimize.B.java

License:Apache License

/**
 * @param block//from  w ww  .  j  a  va  2s  . com
 */
private void OptmizeFirstBlockLdc() {
    Block block = this.blocks.get(0);
    Map<Integer, LdcInsnNode> map = new HashMap<Integer, LdcInsnNode>();
    AbstractInsnNode p = block.first.getNext();
    while (p != null && p != block.last) {
        if (p.getOpcode() == Opcodes.LDC) {
            AbstractInsnNode q = p.getNext();
            if (isWrite(q)) {
                int var = var(q);
                if (block.out.get(var) == q) {
                    Map<Block, Boolean> couldReplace = new HashMap<Block, Boolean>();
                    Set<Block> replacedBlock = new HashSet<Block>();
                    replacedBlock.add(block);
                    couldReplace.put(block, true);
                    LdcInsnNode ldc = (LdcInsnNode) p;
                    boolean remove = true;
                    for (Block subBlock : block.tos) {
                        boolean x = doOptmizeFirstBlockLdc(ldc, var, subBlock, couldReplace, replacedBlock);
                        if (!x) {
                            remove = false;
                        }
                    }
                    if (remove) {
                        insnList.remove(p);
                        p = q.getNext();
                        insnList.remove(q);
                        map.put(var, ldc);
                        continue;
                    }

                }
            }
        } else if (isRead(p)) {
            int var = var(p);
            LdcInsnNode ldc = map.get(var);
            if (ldc != null) {
                AbstractInsnNode q = p.getNext();
                insnList.remove(p);
                insnList.insertBefore(q, ldc.clone(null));
                p = q;
                continue;
            }
        }
        p = p.getNext();
    }
}

From source file:pxb.android.dex2jar.optimize.c.DexInterpreter.java

License:Apache License

@Override
public Value binaryOperation(AbstractInsnNode insn, Value value1, Value value2) throws AnalyzerException {
    switch (insn.getOpcode()) {
    case PUTFIELD:
        FieldInsnNode fieldInsnNode = (FieldInsnNode) insn;
        if (((CBasicValue) value1).getType() == null) {
            ((CBasicValue) value1).setType(Type.getType(fieldInsnNode.owner));
        }/*from   ww w .j a va  2 s.c  o m*/
        if (((CBasicValue) value2).getType() == null) {
            ((CBasicValue) value2).setType(Type.getType(fieldInsnNode.desc));
        }
        break;
    // case IALOAD:
    // case BALOAD:
    // case CALOAD:
    // case SALOAD:
    case IADD:
    case ISUB:
    case IMUL:
    case IDIV:
    case IREM:
    case ISHL:
    case ISHR:
    case IUSHR:
    case IAND:
    case IOR:
    case IXOR:
        if (((CBasicValue) value1).getType() == null) {
            ((CBasicValue) value1).setType(Type.INT_TYPE);
        }
        if (((CBasicValue) value2).getType() == null) {
            ((CBasicValue) value2).setType(Type.INT_TYPE);
        }
        break;
    case FALOAD:
    case FADD:
    case FSUB:
    case FMUL:
    case FDIV:
    case FREM:
    case FCMPL:
    case FCMPG:
        if (((CBasicValue) value1).getType() == null) {
            ((CBasicValue) value1).setType(Type.FLOAT_TYPE);
        }
        if (((CBasicValue) value2).getType() == null) {
            ((CBasicValue) value2).setType(Type.FLOAT_TYPE);
        }
        break;
    case LALOAD:
    case LADD:
    case LSUB:
    case LMUL:
    case LDIV:
    case LREM:
    case LSHL:
    case LSHR:
    case LUSHR:
    case LAND:
    case LOR:
    case LXOR:
    case LCMP:
        if (((CBasicValue) value1).getType() == null) {
            ((CBasicValue) value1).setType(Type.LONG_TYPE);
        }
        if (((CBasicValue) value2).getType() == null) {
            ((CBasicValue) value2).setType(Type.LONG_TYPE);
        }
        break;
    case DALOAD:
    case DADD:
    case DSUB:
    case DMUL:
    case DDIV:
    case DREM:
    case DCMPL:
    case DCMPG:
        if (((CBasicValue) value1).getType() == null) {
            ((CBasicValue) value1).setType(Type.DOUBLE_TYPE);
        }
        if (((CBasicValue) value2).getType() == null) {
            ((CBasicValue) value2).setType(Type.DOUBLE_TYPE);
        }
        break;
    // case AALOAD:
    // return BasicValue.REFERENCE_VALUE;
    case IF_ICMPEQ:
    case IF_ICMPNE:
    case IF_ICMPLT:
    case IF_ICMPGE:
    case IF_ICMPGT:
    case IF_ICMPLE:
        if (((CBasicValue) value1).getType() == null && ((CBasicValue) value2).getType() != null) {
            ((CBasicValue) value1).setType(((CBasicValue) value2).getType());
        }
        if (((CBasicValue) value2).getType() == null && ((CBasicValue) value1).getType() != null) {
            ((CBasicValue) value2).setType(((CBasicValue) value1).getType());
        }
        break;
    case IF_ACMPEQ:
    case IF_ACMPNE:
    }

    return super.binaryOperation(insn, value1, value2);
}

From source file:pxb.android.dex2jar.optimize.c.DexInterpreter.java

License:Apache License

@Override
public Value copyOperation(AbstractInsnNode insn, Value value) throws AnalyzerException {

    // if(Util.isRead(insn)&& value ==null){
    // System.out.println();
    // }/*from www.  j ava  2 s  .  com*/

    switch (insn.getOpcode()) {
    case FLOAD:
    case FSTORE:
        if (((CBasicValue) value).getType() == null) {
            ((CBasicValue) value).setType(Type.FLOAT_TYPE);
            break;
        }
    case DLOAD:
    case DSTORE:
        if (((CBasicValue) value).getType() == null) {
            ((CBasicValue) value).setType(Type.DOUBLE_TYPE);
            break;
        }
    }

    return super.copyOperation(insn, value);
}

From source file:pxb.android.dex2jar.optimize.c.DexInterpreter.java

License:Apache License

@Override
public Value newOperation(AbstractInsnNode insn) throws AnalyzerException {
    switch (insn.getOpcode()) {
    case ACONST_NULL:
        return newValue(Type.getObjectType("null"));
    case ICONST_M1:
    case ICONST_0:
    case ICONST_1:
    case ICONST_2:
    case ICONST_3:
    case ICONST_4:
    case ICONST_5:
        return new CBasicValue(null);
    case LCONST_0:
    case LCONST_1:
        return new CBasicValue(null);
    case FCONST_0:
    case FCONST_1:
    case FCONST_2:
        return CBasicValue.FLOAT_VALUE;
    case DCONST_0:
    case DCONST_1:
        return CBasicValue.DOUBLE_VALUE;
    case BIPUSH:/*  w  w w .  java  2 s .c  o m*/
    case SIPUSH:
        return new CBasicValue(null);
    case LDC:
        Object cst = ((LdcInsnNode) insn).cst;
        if (cst instanceof Integer) {
            return new CBasicValue(null);
        } else if (cst instanceof Float) {
            return CBasicValue.FLOAT_VALUE;
        } else if (cst instanceof Long) {
            return new CBasicValue(null);
        } else if (cst instanceof Double) {
            return CBasicValue.DOUBLE_VALUE;
        } else if (cst instanceof Type) {
            return newValue(Type.getObjectType("java/lang/Class"));
        } else {
            return newValue(Type.getType(cst.getClass()));
        }
    case JSR:
        return CBasicValue.RETURNADDRESS_VALUE;
    case GETSTATIC:
        return newValue(Type.getType(((FieldInsnNode) insn).desc));
    case NEW:
        return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
    default:
        throw new Error("Internal error.");
    }
}

From source file:pxb.android.dex2jar.optimize.c.DexInterpreter.java

License:Apache License

@Override
public Value unaryOperation(AbstractInsnNode insn, Value value) throws AnalyzerException {
    if (((CBasicValue) value).getType() == null) {
        switch (insn.getOpcode()) {
        case INEG:
        case IINC:
        case I2D:
        case I2L:
        case I2F:
        case I2B:
        case I2C:
        case I2S:
        case IRETURN:
        case NEWARRAY:
        case ANEWARRAY:
        case TABLESWITCH:
        case LOOKUPSWITCH:
            ((CBasicValue) value).setType(Type.INT_TYPE);
            break;
        case L2D:
        case L2F:
        case L2I:
        case LRETURN:
        case LNEG:
            ((CBasicValue) value).setType(Type.LONG_TYPE);
            break;

        case DNEG:
        case D2F:
        case D2L:
        case D2I:
        case DRETURN:
            ((CBasicValue) value).setType(Type.DOUBLE_TYPE);
            break;
        case FNEG:
        case F2D:
        case F2L:
        case F2I:
        case FRETURN:
            ((CBasicValue) value).setType(Type.FLOAT_TYPE);
            break;
        case PUTSTATIC:
            ((CBasicValue) value).setType(Type.getType(((FieldInsnNode) insn).desc));
            break;
        case GETFIELD:
            ((CBasicValue) value).setType(Type.getType(((FieldInsnNode) insn).owner));
            break;
        }/*from w w w .j ava 2  s  . c om*/
    }
    if (insn.getOpcode() == GETFIELD) {
        return new CBasicValue(Type.getType(((FieldInsnNode) insn).desc));
    }
    return super.unaryOperation(insn, value);
}