read enhanced bytecode postions from class attributes
This commit is contained in:
parent
d7ebb57ee6
commit
47711fd310
|
@ -19,6 +19,7 @@ import com.ibm.wala.cfg.AbstractCFG;
|
|||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.shrikeCT.InvalidClassFileException;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.types.Descriptor;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
|
@ -249,6 +250,15 @@ public abstract class AstMethod implements IMethod {
|
|||
public int getNumberOfParameters() {
|
||||
return symtab.getParameterValueNumbers().length;
|
||||
}
|
||||
/** BEGIN Custom change: precise bytecode positions */
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.IMethod#getParameterSourcePosition(int)
|
||||
*/
|
||||
public SourcePosition getParameterSourcePosition(int paramNum) throws InvalidClassFileException {
|
||||
return null;
|
||||
}
|
||||
/** END Custom change: precise bytecode positions */
|
||||
|
||||
public int getLineNumber(int instructionIndex) {
|
||||
Position pos = debugInfo.getInstructionPosition(instructionIndex);
|
||||
|
|
|
@ -15,6 +15,8 @@ import java.io.InputStream;
|
|||
import java.net.URL;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.classLoader.IMethod.SourcePosition;
|
||||
|
||||
/**
|
||||
* The assumption is that a typical CAst is derived from some kind of
|
||||
* textual source file, for which it makes sense to record source
|
||||
|
@ -35,13 +37,7 @@ public interface CAstSourcePositionMap {
|
|||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*/
|
||||
public interface Position extends Comparable {
|
||||
int getFirstLine();
|
||||
int getLastLine();
|
||||
int getFirstCol();
|
||||
int getLastCol();
|
||||
int getFirstOffset();
|
||||
int getLastOffset();
|
||||
public interface Position extends SourcePosition {
|
||||
URL getURL();
|
||||
InputStream getInputStream() throws IOException;
|
||||
}
|
||||
|
|
|
@ -122,7 +122,22 @@ public interface IMethod extends IMember, ContextItem {
|
|||
* @return the source line number corresponding to a particular bytecode index, or -1 if the information is not available.
|
||||
*/
|
||||
int getLineNumber(int bcIndex);
|
||||
/** BEGIN Custom change: precise positions */
|
||||
|
||||
public interface SourcePosition extends Comparable {
|
||||
int getFirstLine();
|
||||
int getLastLine();
|
||||
int getFirstCol();
|
||||
int getLastCol();
|
||||
int getFirstOffset();
|
||||
int getLastOffset();
|
||||
}
|
||||
|
||||
SourcePosition getSourcePosition(int instructionIndex) throws InvalidClassFileException;
|
||||
|
||||
SourcePosition getParameterSourcePosition(int paramNum) throws InvalidClassFileException;
|
||||
/** END Custom change: precise positions */
|
||||
|
||||
/**
|
||||
* @return the (source code) name of the local variable of a given number at the specified program counter, or null if the
|
||||
* information is not available.
|
||||
|
|
|
@ -96,7 +96,21 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
|
|||
* Mapping from instruction index to program counter.
|
||||
*/
|
||||
private int[] pcMap;
|
||||
|
||||
/** BEGIN Custom change: precise positions */
|
||||
|
||||
/**
|
||||
* Cached map representing position information for bytecode instruction
|
||||
* at given index
|
||||
*/
|
||||
protected SourcePosition[] positionMap;
|
||||
|
||||
/**
|
||||
* Sourcecode positions for method parameters
|
||||
*/
|
||||
protected SourcePosition[] paramPositionMap;
|
||||
|
||||
/** END Custom change: precise positions */
|
||||
|
||||
/**
|
||||
* Cached map representing line number information in ShrikeCT format TODO: do more careful caching than just soft references
|
||||
*/
|
||||
|
@ -740,6 +754,22 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
/** BEGIN Custom change: precise bytecode positions */
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.IMethod#getSourcePosition(int)
|
||||
*/
|
||||
public SourcePosition getSourcePosition(int bcIndex) throws InvalidClassFileException {
|
||||
return (getBCInfo().positionMap == null) ? null : getBCInfo().positionMap[bcIndex];
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.IMethod#getParameterSourcePosition(int)
|
||||
*/
|
||||
public SourcePosition getParameterSourcePosition(int paramNum) throws InvalidClassFileException {
|
||||
return (getBCInfo().paramPositionMap == null) ? null : getBCInfo().paramPositionMap[paramNum];
|
||||
}
|
||||
/** END Custom change: precise bytecode positions */
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.IMethod#getLineNumber(int)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.classLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -19,7 +20,9 @@ import com.ibm.wala.shrikeBT.Decoder;
|
|||
import com.ibm.wala.shrikeBT.IndirectionData;
|
||||
import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder;
|
||||
import com.ibm.wala.shrikeCT.AnnotationsReader;
|
||||
import com.ibm.wala.shrikeCT.AnnotationsReader.UnimplementedException;
|
||||
import com.ibm.wala.shrikeCT.ClassReader;
|
||||
import com.ibm.wala.shrikeCT.ClassReader.AttrIterator;
|
||||
import com.ibm.wala.shrikeCT.CodeReader;
|
||||
import com.ibm.wala.shrikeCT.ExceptionsReader;
|
||||
import com.ibm.wala.shrikeCT.InvalidClassFileException;
|
||||
|
@ -28,8 +31,8 @@ import com.ibm.wala.shrikeCT.LocalVariableTableReader;
|
|||
import com.ibm.wala.shrikeCT.RuntimeInvisibleAnnotationsReader;
|
||||
import com.ibm.wala.shrikeCT.RuntimeVisibleAnnotationsReader;
|
||||
import com.ibm.wala.shrikeCT.SignatureReader;
|
||||
import com.ibm.wala.shrikeCT.AnnotationsReader.UnimplementedException;
|
||||
import com.ibm.wala.shrikeCT.ClassReader.AttrIterator;
|
||||
import com.ibm.wala.shrikeCT.SourcePositionTableReader;
|
||||
import com.ibm.wala.shrikeCT.SourcePositionTableReader.Position;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.types.annotations.Annotation;
|
||||
import com.ibm.wala.types.generics.MethodTypeSignature;
|
||||
|
@ -146,12 +149,115 @@ public final class ShrikeCTMethod extends ShrikeBTMethod implements IBytecodeMet
|
|||
return reader.getClasses();
|
||||
}
|
||||
}
|
||||
/** BEGIN Custom change: precise positions */
|
||||
|
||||
private static final class SPos implements SourcePosition {
|
||||
|
||||
final int firstLine;
|
||||
final int lastLine;
|
||||
final int firstCol;
|
||||
final int lastCol;
|
||||
|
||||
private SPos(int firstLine, int lastLine, int firstCol, int lastCol) {
|
||||
this.firstLine = firstLine;
|
||||
this.lastLine = lastLine;
|
||||
this.firstCol = firstCol;
|
||||
this.lastCol = lastCol;
|
||||
}
|
||||
|
||||
|
||||
public int getFirstCol() {
|
||||
return firstCol;
|
||||
}
|
||||
|
||||
public int getFirstLine() {
|
||||
return firstLine;
|
||||
}
|
||||
|
||||
public int getFirstOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getLastCol() {
|
||||
return lastCol;
|
||||
}
|
||||
|
||||
public int getLastLine() {
|
||||
return lastLine;
|
||||
}
|
||||
|
||||
public int getLastOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int compareTo(Object o) {
|
||||
if (o instanceof SourcePosition) {
|
||||
SourcePosition p = (SourcePosition) o;
|
||||
if (firstLine != p.getFirstLine()) {
|
||||
return firstLine - p.getFirstLine();
|
||||
} else if (firstCol != p.getFirstCol()) {
|
||||
return firstCol - p.getFirstCol();
|
||||
} else if (lastLine != p.getLastLine()) {
|
||||
return lastLine - p.getLastLine();
|
||||
} else if (lastCol != p.getLastCol()) {
|
||||
return lastCol - p.getLastCol();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + firstLine + "," + firstCol + "-" + lastLine + "," + lastCol + ")";
|
||||
}
|
||||
|
||||
}
|
||||
/** END Custom change: precise positions */
|
||||
|
||||
@Override
|
||||
protected void processDebugInfo(BytecodeInfo bcInfo) throws InvalidClassFileException {
|
||||
CodeReader cr = getCodeReader();
|
||||
bcInfo.lineNumberMap = LineNumberTableReader.makeBytecodeToSourceMap(cr);
|
||||
bcInfo.localVariableMap = LocalVariableTableReader.makeVarMap(cr);
|
||||
/** BEGIN Custom change: precise bytecode positions */
|
||||
|
||||
Position param = null;
|
||||
try {
|
||||
param = SourcePositionTableReader.findParameterPosition(shrikeMethodIndex, cr);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
bcInfo.paramPositionMap = new SPos[getNumberOfParameters()];
|
||||
if (param != null) {
|
||||
SPos paramPos = new SPos(param.firstLine, param.lastLine, param.firstCol, param.lastCol);
|
||||
for (int i = 0; i < getNumberOfParameters(); i++) {
|
||||
bcInfo.paramPositionMap[i] = paramPos;
|
||||
}
|
||||
}
|
||||
|
||||
Position pos[] = null;
|
||||
try {
|
||||
pos = SourcePositionTableReader.makeBytecodeToPositionMap(cr);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (pos == null && bcInfo.lineNumberMap != null) {
|
||||
pos = SourcePositionTableReader.makeLineNumberToPositionMap(bcInfo.lineNumberMap);
|
||||
}
|
||||
|
||||
if (pos != null) {
|
||||
bcInfo.positionMap = new SPos[pos.length];
|
||||
for (int i = 0; i < pos.length; i++) {
|
||||
Position p = pos[i];
|
||||
bcInfo.positionMap[i] = new SPos(p.firstLine, p.lastLine, p.firstCol, p.lastCol);
|
||||
}
|
||||
}
|
||||
/** END Custom change: : precise bytecode positions */
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -308,6 +308,22 @@ public class SyntheticMethod implements IMethod {
|
|||
public Descriptor getDescriptor() {
|
||||
return method.getSelector().getDescriptor();
|
||||
}
|
||||
/** BEGIN Custom change: : precise bytecode positions */
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.IMethod#getSourcePosition(int)
|
||||
*/
|
||||
public SourcePosition getSourcePosition(int bcIndex) throws InvalidClassFileException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.IMethod#getParameterSourcePosition(int)
|
||||
*/
|
||||
public SourcePosition getParameterSourcePosition(int paramNum) throws InvalidClassFileException {
|
||||
return null;
|
||||
}
|
||||
/** END Custom change: precise bytecode positions */
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.IMethod#getLineNumber(int)
|
||||
|
|
|
@ -16,3 +16,4 @@ Export-Package: com.ibm.wala.shrike.bench,
|
|||
com.ibm.wala.shrikeBT.tools,
|
||||
com.ibm.wala.shrikeCT
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Require-Bundle: joana.jSDG.SourceInfo;bundle-version="0.0.2"
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
package com.ibm.wala.shrikeCT;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import joana.sourceinfo.CRTable;
|
||||
import joana.sourceinfo.MethodPositions;
|
||||
import joana.sourceinfo.Range;
|
||||
|
||||
import com.ibm.wala.shrikeCT.ClassReader.AttrIterator;
|
||||
|
||||
public final class SourcePositionTableReader extends AttributeReader {
|
||||
|
||||
protected SourcePositionTableReader(AttrIterator attr) throws InvalidClassFileException {
|
||||
super(attr, CRTable.ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
public static final class Position implements Comparable<Object> {
|
||||
|
||||
public final int firstLine;
|
||||
public final int lastLine;
|
||||
public final int firstCol;
|
||||
public final int lastCol;
|
||||
|
||||
private Position(int firstLine, int lastLine, int firstCol, int lastCol) {
|
||||
this.firstLine = firstLine;
|
||||
this.lastLine = lastLine;
|
||||
this.firstCol = firstCol;
|
||||
this.lastCol = lastCol;
|
||||
}
|
||||
|
||||
public int compareTo(Object o) {
|
||||
if (o instanceof Position) {
|
||||
Position p = (Position) o;
|
||||
if (firstLine != p.firstLine) {
|
||||
return firstLine - p.firstLine;
|
||||
} else if (firstCol != p.firstCol) {
|
||||
return firstCol - p.firstCol;
|
||||
} else if (lastLine != p.lastLine) {
|
||||
return lastLine - p.lastLine;
|
||||
} else if (lastCol != p.lastCol) {
|
||||
return lastCol - p.lastCol;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Position findParameterPosition(int methodNr, CodeReader code) throws InvalidClassFileException, IOException {
|
||||
if (code == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
Position params = null;
|
||||
|
||||
// read parameter positions
|
||||
{
|
||||
ClassReader.AttrIterator cIter = new ClassReader.AttrIterator();
|
||||
ClassReader cr = code.getClassReader();
|
||||
cr.initMethodAttributeIterator(methodNr, cIter);
|
||||
|
||||
for (;cIter.isValid(); cIter.advance()) {
|
||||
if (MethodPositions.ATTRIBUTE_NAME.equals(cIter.getName())) {
|
||||
byte data[] = getData(cr, cIter.getRawOffset(), cIter.getRawSize());
|
||||
MethodPositions mPos = new MethodPositions(data);
|
||||
Range r = mPos.getMethodInfo();
|
||||
params = convert(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
public static Position[] makeBytecodeToPositionMap(CodeReader code) throws InvalidClassFileException, IOException {
|
||||
if (code == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
Position pos[] = null;
|
||||
ClassReader.AttrIterator iter = new ClassReader.AttrIterator();
|
||||
code.initAttributeIterator(iter);
|
||||
|
||||
for (; iter.isValid(); iter.advance()) {
|
||||
if (CRTable.ATTRIBUTE_NAME.equals(iter.getName())) {
|
||||
if (pos == null) {
|
||||
pos = new Position[code.getBytecodeLength()];
|
||||
}
|
||||
|
||||
SourcePositionTableReader spRead = new SourcePositionTableReader(iter);
|
||||
spRead.fillBytecodeToPositionMap(pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (pos != null) {
|
||||
// fill in gaps
|
||||
Position last = new Position(0, 0, 0, 0);
|
||||
for (int i = 0; i < pos.length; i++) {
|
||||
Position cur = pos[i];
|
||||
if (cur == null) {
|
||||
pos[i] = last;
|
||||
} else {
|
||||
last = cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
private static final int ATTRIBUTE_HEADER_SIZE = 6;
|
||||
|
||||
private static final byte[] getData(ClassReader cr, int rawOffset, int rawSize) {
|
||||
// prepare raw data of attribute to pass to sourceinfo
|
||||
byte klass[] = cr.getBytes();
|
||||
int size = rawSize - ATTRIBUTE_HEADER_SIZE;
|
||||
byte data[] = new byte[size];
|
||||
System.arraycopy(klass, rawOffset + ATTRIBUTE_HEADER_SIZE, data, 0, size);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private void fillBytecodeToPositionMap(Position[] pos) throws IOException {
|
||||
byte tableData[] = getData(getClassReader(), getRawOffset(), getRawSize());
|
||||
|
||||
CRTable crTable = new CRTable(tableData);
|
||||
|
||||
for (int pc = 0; pc < pos.length; pc++) {
|
||||
Range r = crTable.getSourceInfo(pc);
|
||||
Position p = convert(r);
|
||||
pos[pc] = p;
|
||||
}
|
||||
}
|
||||
|
||||
private final static Position convert(Range r) {
|
||||
Position pos = null;
|
||||
|
||||
if (r != null) {
|
||||
joana.sourceinfo.Position start = r.getStartPosition();
|
||||
joana.sourceinfo.Position end = r.getEndPosition();
|
||||
|
||||
if (start != null && !start.isUndefined()) {
|
||||
if (end != null && !end.isUndefined()) {
|
||||
pos = new Position(start.getLine(), end.getLine(), start.getColumn(), end.getColumn());
|
||||
} else {
|
||||
pos = new Position(start.getLine(), start.getLine(), -1, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
public static Position[] makeLineNumberToPositionMap(int[] lineNumberMap) {
|
||||
Position pos[] = new Position[lineNumberMap.length];
|
||||
|
||||
for (int i = 0; i < pos.length; i++) {
|
||||
int line = lineNumberMap[i];
|
||||
pos[i] = new Position(line, line, -1, -1);
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue