Mercurial > hg > icedrobot > daneel
changeset 72:57fe21b3757e
Added method to identify jump target labels.
Reviewed-by: Remi Forax
* dex/Label.java (isJumpTarget): Added new abstract method.
* dex/Code.java: Correctly mark jump target labels.
* dex/DebugInfo.java: Likewise.
author | Michael Starzinger <michi@complang.tuwien.ac.at> |
---|---|
date | Wed, 23 Mar 2011 23:18:49 +0100 |
parents | e2aee3228a72 |
children | 15cfcc7a8756 |
files | src/main/java/org/icedrobot/daneel/dex/Code.java src/main/java/org/icedrobot/daneel/dex/DebugInfo.java src/main/java/org/icedrobot/daneel/dex/Label.java |
diffstat | 3 files changed, 62 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/org/icedrobot/daneel/dex/Code.java Wed Mar 23 11:00:12 2011 +0100 +++ b/src/main/java/org/icedrobot/daneel/dex/Code.java Wed Mar 23 23:18:49 2011 +0100 @@ -131,8 +131,8 @@ } ByteBuffer buf = buffer.slice(); for (int i = 0; i < triesSize; i++) { - Label startLabel = putLabel(startAddr[i]); - Label endLabel = putLabel(startAddr[i] + insnCount[i]); + Label startLabel = putLabel(startAddr[i], false); + Label endLabel = putLabel(startAddr[i] + insnCount[i], false); buf.position(handlerOff[i]); // Note that size is a signed value here, which indicates // whether the try-block has a catch-all handler or not. @@ -730,7 +730,7 @@ */ private void addTryCatch(Label startLabel, Label endLabel, String type, int handlerAddr) { - Label handlerLabel = putLabel(handlerAddr); + Label handlerLabel = putLabel(handlerAddr, true); TryCatchInfo info = new TryCatchInfo(startLabel, endLabel, handlerLabel, type); tryCatchInfos.add(info); @@ -761,15 +761,25 @@ * which call it, to avoid trampoline code. * * @param pos The given bytecode position in 16-bit code units. + * @param jumpTarget Indicates whether the label should be marked as a jump + * target or not. That information can be useful for the visitor and + * is passed out through the {@link Label#isJumpTarget()} method. * @return The associated label, never returns {@code null}. */ - Label putLabel(int pos) { + Label putLabel(int pos, boolean jumpTarget) { if (pos < 0 || pos >= insnsSize) throw new DexParseException("Label position out of range: " + pos); Label label = labelMap.get(pos); if (label == null) { - label = new DebugLabel(pos); + label = new DebugLabel(pos, jumpTarget); labelMap.put(pos, label); + } else { + if (jumpTarget & !label.isJumpTarget()) { + if (!(label instanceof DebugLabel)) + throw new DexParseException("Cannot mark label as target."); + DebugLabel debugLabel = (DebugLabel) label; + debugLabel.setJumpTarget(); + } } return label; } @@ -830,7 +840,7 @@ case GOTO: // Format 10t: AA|op // Syntax: op +AA - putLabel(pos + (s1 >> 8)); + putLabel(pos + (s1 >> 8), true); break; case GOTO_16: @@ -856,7 +866,7 @@ case IF_LEZ: // Format 21t: AA|op BBBB // Syntax: op vAA, +BBBB - putLabel(pos + s2); + putLabel(pos + s2, true); break; case FILL_ARRAY_DATA: @@ -961,12 +971,17 @@ int firstKey = buffer.getInt(); int[] targets = BufferUtil.getInts(buffer, size); for (int i = 0; i < size; i++) - map.put(firstKey + i, putLabel(pos + targets[i])); + map.put(firstKey + i, putLabel(pos + targets[i], true)); } public int length() { return (size * 2) + 4; } + + @Override + public boolean isJumpTarget() { + return false; + } }; /** @@ -984,12 +999,17 @@ int[] keys = BufferUtil.getInts(buffer, size); int[] targets = BufferUtil.getInts(buffer, size); for (int i = 0; i < size; i++) - map.put(keys[i], putLabel(pos + targets[i])); + map.put(keys[i], putLabel(pos + targets[i], true)); } public int length() { return (size * 4) + 2; } + + @Override + public boolean isJumpTarget() { + return false; + } }; /** @@ -1012,22 +1032,38 @@ public int length() { return (size * elementWidth + 1) / 2 + 4; } + + @Override + public boolean isJumpTarget() { + return false; + } }; /** * A label as defined by the interface, but enriched with additional debug * information. */ - private static class DebugLabel extends Label { + static class DebugLabel extends Label { private final int pos; + private boolean jumpTarget; - public DebugLabel(int pos) { + public DebugLabel(int pos, boolean jumpTarget) { this.pos = pos; + this.jumpTarget = jumpTarget; + } + + @Override + public boolean isJumpTarget() { + return jumpTarget; + } + + public void setJumpTarget() { + this.jumpTarget = true; } @Override public String toString() { - return String.format("L%03d", pos); + return String.format("L%03d%s", pos, jumpTarget ? "*" : ""); } }; }
--- a/src/main/java/org/icedrobot/daneel/dex/DebugInfo.java Wed Mar 23 11:00:12 2011 +0100 +++ b/src/main/java/org/icedrobot/daneel/dex/DebugInfo.java Wed Mar 23 23:18:49 2011 +0100 @@ -41,6 +41,7 @@ import java.util.LinkedList; import java.util.List; +import org.icedrobot.daneel.dex.Code.DebugLabel; import org.icedrobot.daneel.util.BufferUtil; /** @@ -194,7 +195,7 @@ // XXX Check why this happens, this shouldn't happen. //throw new DexParseException("No live local in register."); break; - local.setEnd(code.putLabel(addr)); + local.setEnd(code.putLabel(addr, false)); break; case DBG_RESTART_LOCAL: @@ -243,7 +244,7 @@ */ private LocalVariable emitLocalVariable(int regNum, int startAddr, int nameIdx, int typeIdx, int sigIdx) { - Label startLabel = code.putLabel(startAddr); + Label startLabel = code.putLabel(startAddr, false); LocalVariable local = new LocalVariable(regNum, nameIdx, typeIdx, sigIdx, startLabel); localVariables.add(local); @@ -301,18 +302,17 @@ * A label as defined by the interface, but enriched with additional debug * and line number information. */ - static class LineNumberLabel extends Label { - private final int pos; + static class LineNumberLabel extends DebugLabel { final int line; public LineNumberLabel(int pos, int line) { - this.pos = pos; + super(pos, false); this.line = line; } @Override public String toString() { - return String.format("L%03d[line=%d]", pos, line); + return String.format("%s[line=%d]", super.toString(), line); } }; }
--- a/src/main/java/org/icedrobot/daneel/dex/Label.java Wed Mar 23 11:00:12 2011 +0100 +++ b/src/main/java/org/icedrobot/daneel/dex/Label.java Wed Mar 23 23:18:49 2011 +0100 @@ -40,6 +40,13 @@ /** * A label referencing a certain position in Dalvik VM bytecode. */ -public class Label { +public abstract class Label { + /** + * Checks whether this label is used as a jump target for any instruction in + * the code it is associated with. + * + * @return True if label is used as jump target, false otherwise. + */ + public abstract boolean isJumpTarget(); }