⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crtable.java

📁 java编译器gjc源码 java编译环境
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * @(#)CRTable.java	1.9 03/01/23
 *
 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.sun.tools.javac.v8.code;
import com.sun.tools.javac.v8.tree.*;

import com.sun.tools.javac.v8.util.*;

import com.sun.tools.javac.v8.tree.Tree.*;


/**
 * This class contains the CharacterRangeTable for some method
 *  and the hashtable for mapping trees or lists of trees to their
 *  ending positions.
 */
public class CRTable implements CRTFlags {
    private final boolean crtDebug = false;

    /**
     * The list of CRTable entries.
     */
    private ListBuffer entries = new ListBuffer();

    /**
     * The hashtable for source positions.
     */
    private Hashtable positions = Hashtable.make();

    /**
     * The hashtable for ending positions stored in the parser.
     */
    private Hashtable endPositions;

    /**
     * The tree of the method this table is intended for.
     *  We should traverse this tree to get source ranges.
     */
    Tree.MethodDef methodTree;

    /**
     * Constructor
     */
    public CRTable(Tree.MethodDef tree, Hashtable endPositions) {
        super();
        this.methodTree = tree;
        this.endPositions = endPositions;
    }

    /**
      * Create a new CRTEntry and add it to the entries.
      *  @param tree     The tree or the list of trees for which
      *                  we are storing the code pointers.
      *  @param flags    The set of flags designating type of the entry.
      *  @param startPc  The starting code position.
      *  @param endPc    The ending code position.
      */
    public void put(Object tree, int flags, int startPc, int endPc) {
        entries.append(new CRTEntry(tree, flags, startPc, endPc));
    }

    /**
      * Compute source positions and write CRT to the databuf.
      *  @param databuf  The buffer to write bytecodes to.
      */
    public int writeCRT(ByteBuffer databuf) {
        int crtEntries = 0;
        new SourceComputer().csp(methodTree);
        for (List l = entries.toList(); l.nonEmpty(); l = l.tail) {
            CRTEntry entry = (CRTable.CRTEntry) l.head;
            if (entry.startPc == entry.endPc)
                continue;
            SourceRange pos = (CRTable.SourceRange) positions.get(entry.tree);
            assert pos != null :
            "CRT: tree source positions are undefined";
            if ((pos.startPos == Position.NOPOS) || (pos.endPos == Position.NOPOS))
                continue;
            if (crtDebug) {
                System.out.println("Tree: " + entry.tree + ", type:" +
                        getTypes(entry.flags));
                System.out.println("Start: line = " +
                        Position.line(pos.startPos) + ", col = " +
                        Position.column(pos.startPos) + ", pc = " + entry.startPc);
                System.out.println("End:   line = " + Position.line(pos.endPos) +
                        ", col = " + Position.column(pos.endPos) + ", pc = " +
                        (entry.endPc - 1));
            }
            databuf.appendChar(entry.startPc);
            databuf.appendChar(entry.endPc - 1);
            databuf.appendInt(pos.startPos);
            databuf.appendInt(pos.endPos);
            databuf.appendChar(entry.flags);
            crtEntries++;
        }
        return crtEntries;
    }

    /**
      * Return the number of the entries.
      */
    public int length() {
        return entries.length();
    }

    /**
      * Return string describing flags enabled.
      */
    private String getTypes(int flags) {
        String types = "";
        if ((flags & CRT_STATEMENT) != 0)
            types += " CRT_STATEMENT";
        if ((flags & CRT_BLOCK) != 0)
            types += " CRT_BLOCK";
        if ((flags & CRT_ASSIGNMENT) != 0)
            types += " CRT_ASSIGNMENT";
        if ((flags & CRT_FLOW_CONTROLLER) != 0)
            types += " CRT_FLOW_CONTROLLER";
        if ((flags & CRT_FLOW_TARGET) != 0)
            types += " CRT_FLOW_TARGET";
        if ((flags & CRT_INVOKE) != 0)
            types += " CRT_INVOKE";
        if ((flags & CRT_CREATE) != 0)
            types += " CRT_CREATE";
        if ((flags & CRT_BRANCH_TRUE) != 0)
            types += " CRT_BRANCH_TRUE";
        if ((flags & CRT_BRANCH_FALSE) != 0)
            types += " CRT_BRANCH_FALSE";
        return types;
    }

    /**
      *
      *  This class contains methods to compute source positions for trees.
      *  Extends Tree.Visitor to traverse the abstract syntax tree.
      */
    class SourceComputer extends Tree.Visitor {

        SourceComputer() {
            super();
        }

        /**
          * The result of the tree traversal methods.
          */
        SourceRange result;

        /**
         * Visitor method: compute source positions for a single node.
         */
        public SourceRange csp(Tree tree) {
            if (tree == null)
                return null;
            tree.accept(this);
            if (result != null) {
                positions.put(tree, result);
            }
            return result;
        }

        /**
          * Visitor method: compute source positions for a list of nodes.
          */
        public SourceRange csp(List trees) {
            if ((trees == null) || !(trees.nonEmpty()))
                return null;
            SourceRange list_sr = new SourceRange();
            for (List l = trees; l.nonEmpty(); l = l.tail) {
                list_sr.mergeWith(csp((Tree) l.head));
            }
            positions.put(trees, list_sr);
            return list_sr;
        }

        /**
          * Visitor method: compute source positions for
          *    a list of case blocks of switch statements.
          */
        public SourceRange cspCases(List trees) {
            if ((trees == null) || !(trees.nonEmpty()))
                return null;
            SourceRange list_sr = new SourceRange();
            for (List l = trees; l.nonEmpty(); l = l.tail) {
                list_sr.mergeWith(csp((Tree) l.head));
            }
            positions.put(trees, list_sr);
            return list_sr;
        }

        /**
          * Visitor method: compute source positions for
          *   a list of catch clauses in try statements.
          */
        public SourceRange cspCatchers(List trees) {
            if ((trees == null) || !(trees.nonEmpty()))
                return null;
            SourceRange list_sr = new SourceRange();
            for (List l = trees; l.nonEmpty(); l = l.tail) {
                list_sr.mergeWith(csp((Tree) l.head));
            }
            positions.put(trees, list_sr);
            return list_sr;
        }

        public void visitMethodDef(MethodDef tree) {
            SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
            sr.mergeWith(csp(tree.body));
            result = sr;
        }

        public void visitVarDef(VarDef tree) {
            SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
            csp(tree.vartype);
            sr.mergeWith(csp(tree.init));
            result = sr;
        }

        public void visitSkip(Skip tree) {
            SourceRange sr = new SourceRange(startPos(tree), startPos(tree));
            result = sr;
        }

        public void visitBlock(Block tree) {
            SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
            csp(tree.stats);
            result = sr;
        }

        public void visitDoLoop(DoLoop tree) {
            SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
            sr.mergeWith(csp(tree.body));
            sr.mergeWith(csp(tree.cond));
            result = sr;
        }

        public void visitWhileLoop(WhileLoop tree) {
            SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
            sr.mergeWith(csp(tree.cond));
            sr.mergeWith(csp(tree.body));
            result = sr;
        }

        public void visitForLoop(ForLoop tree) {
            SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
            sr.mergeWith(csp(tree.init));
            sr.mergeWith(csp(tree.cond));
            sr.mergeWith(csp(tree.step));
            sr.mergeWith(csp(tree.body));
            result = sr;
        }

        public void visitLabelled(Labelled tree) {
            SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
            sr.mergeWith(csp(tree.body));
            result = sr;
        }

        public void visitSwitch(Switch tree) {
            SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
            sr.mergeWith(csp(tree.selector));
            sr.mergeWith(cspCases(tree.cases));
            result = sr;
        }

        public void visitCase(Case tree) {
            SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
            sr.mergeWith(csp(tree.pat));
            sr.mergeWith(csp(tree.stats));
            result = sr;
        }

        public void visitSynchronized(Synchronized tree) {
            SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
            sr.mergeWith(csp(tree.lock));
            sr.mergeWith(csp(tree.body));
            result = sr;
        }

        public void visitTry(Try tree) {
            SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
            sr.mergeWith(csp(tree.body));
            sr.mergeWith(cspCatchers(tree.catchers));
            sr.mergeWith(csp(tree.finalizer));
            result = sr;
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -