org.mbte.groovypp.compiler.asm.StoringMethodVisitor.java Source code

Java tutorial

Introduction

Here is the source code for org.mbte.groovypp.compiler.asm.StoringMethodVisitor.java

Source

/*
 * Copyright 2009-2011 MBTE Sweden AB.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.mbte.groovypp.compiler.asm;

import org.objectweb.asm.*;

import java.util.*;

public class StoringMethodVisitor implements MethodVisitor {
    public final List<AsmInstr> operations = new LinkedList<AsmInstr>();

    public void visitLabel(Label label) {
        operations.add(new VisitLabel(label));
    }

    public void visitJumpInsn(int opcode, Label label) {
        operations.add(new VisitJumpInsn(opcode, label));
    }

    public void visitInsn(int opcode) {
        operations.add(new VisitInsn(opcode));
    }

    public void visitIntInsn(int opcode, int operand) {
        operations.add(new VisitIntInsn(opcode, operand));
    }

    public void visitVarInsn(int opcode, int var) {
        operations.add(new VisitVarInsn(opcode, var));
    }

    public void visitTypeInsn(int opcode, String type) {
        operations.add(new VisitTypeInsn(opcode, type));
    }

    public void visitFieldInsn(int opcode, String owner, String name, String type) {
        operations.add(new VisitFieldInsn(opcode, owner, name, type));
    }

    public void visitMethodInsn(int opcode, String owner, String name, String descr) {
        operations.add(new VisitMethodInsn(opcode, owner, name, descr));
    }

    public void visitLdcInsn(Object value) {
        operations.add(new VisitLdcInsn(value));
    }

    public void visitIincInsn(int var, int increment) {
        operations.add(new VisitIincInsn(var, increment));
    }

    public void visitMultiANewArrayInsn(String s, int i) {
        operations.add(new VisitMultiANewArrayInsn(s, i));
    }

    public void visitTryCatchBlock(Label label, Label label1, Label label2, String s) {
        operations.add(new VisitTryCatchBlock(label, label1, label2, s));
    }

    public void visitLocalVariable(String s, String s1, String s2, Label label, Label label1, int i) {
        operations.add(new VisitLocalVariable(s, s1, label, label1, i));
    }

    public void visitLineNumber(int line, Label label) {
        operations.add(new VisitLineNumber(line, label));
    }

    static class Redirects extends IdentityHashMap<Label, Label> {
        private Label redirect(Label label) {
            Label redir = get(label);
            return redir != null ? redir : label;
        }
    }

    public void redirect() {
        Redirects redirects = new Redirects();

        Label curLabel = null;
        for (Iterator<AsmInstr> i = operations.iterator(); i.hasNext();) {
            AsmInstr ii = i.next();

            if (ii instanceof VisitLabel) {
                VisitLabel visitLabel = (VisitLabel) ii;
                if (curLabel != null) {
                    redirects.put(visitLabel.label, curLabel);
                    i.remove();
                } else {
                    curLabel = visitLabel.label;
                }
            } else {
                curLabel = null;
            }
        }

        for (AsmInstr i : operations) {
            if (i instanceof VisitJumpInsn) {
                VisitJumpInsn jumpInsn = (VisitJumpInsn) i;
                jumpInsn.label = redirects.redirect(jumpInsn.label);
                continue;
            }

            if (i instanceof VisitLocalVariable) {
                VisitLocalVariable localVariable = (VisitLocalVariable) i;
                localVariable.start = redirects.redirect(localVariable.start);
                localVariable.end = redirects.redirect(localVariable.end);
                continue;
            }

            if (i instanceof VisitTryCatchBlock) {
                VisitTryCatchBlock tryCatchBlock = (VisitTryCatchBlock) i;
                tryCatchBlock.start = redirects.redirect(tryCatchBlock.start);
                tryCatchBlock.end = redirects.redirect(tryCatchBlock.end);
                tryCatchBlock.handler = redirects.redirect(tryCatchBlock.handler);
                continue;
            }

            if (i instanceof VisitLineNumber) {
                VisitLineNumber lineNumber = (VisitLineNumber) i;
                lineNumber.label = redirects.redirect(lineNumber.label);
                continue;
            }
        }

        redirects.clear();

        for (int i = 1; i < operations.size(); ++i) {
            AsmInstr instr = operations.get(i);
            if (instr instanceof VisitJumpInsn) {
                VisitJumpInsn jumpInsn = (VisitJumpInsn) instr;
                if (jumpInsn.opcode == Opcodes.GOTO) {
                    AsmInstr prevInstr = operations.get(i - 1);
                    if (prevInstr instanceof VisitLabel) {
                        redirects.put(((VisitLabel) prevInstr).label, jumpInsn.label);
                    }
                }
            }
        }

        if (redirects.size() > 0) {
            for (AsmInstr instr : operations) {
                if (instr instanceof VisitJumpInsn) {
                    VisitJumpInsn jumpInsn = (VisitJumpInsn) instr;
                    jumpInsn.label = redirects.redirect(jumpInsn.label);
                }
            }
        }
    }

    public void visitTableSwitchInsn(int i, int i1, Label label, Label[] labels) {
        throw new UnsupportedOperationException();
    }

    public void visitLookupSwitchInsn(Label label, int[] ints, Label[] labels) {
        throw new UnsupportedOperationException();
    }

    public void visitMaxs(int i, int i1) {
        throw new UnsupportedOperationException();
    }

    public void visitEnd() {
        throw new UnsupportedOperationException();
    }

    public AnnotationVisitor visitAnnotationDefault() {
        throw new UnsupportedOperationException();
    }

    public AnnotationVisitor visitAnnotation(String s, boolean b) {
        throw new UnsupportedOperationException();
    }

    public AnnotationVisitor visitParameterAnnotation(int i, String s, boolean b) {
        throw new UnsupportedOperationException();
    }

    public void visitAttribute(Attribute attribute) {
        throw new UnsupportedOperationException();
    }

    public void visitCode() {
        throw new UnsupportedOperationException();
    }

    public void visitFrame(int i, int i1, Object[] objects, int i2, Object[] objects1) {
        throw new UnsupportedOperationException();
    }
}