📄 crtable.java
字号:
/**
* @(#)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 + -