--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2002 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * PARC initial implementation
+ * Andy Clement pushed down into bcel module
+ * ******************************************************************/
+
+
+package org.aspectj.apache.bcel.generic;
+
+/** we don't actually target instructions, but instructions target us. */
+public class LineNumberTag extends Tag {
+
+ private final int lineNumber;
+
+ public LineNumberTag(int lineNumber) {
+ this.lineNumber = lineNumber;
+ }
+
+ public int getLineNumber() { return lineNumber; }
+
+ // ---- from Object
+
+ public String toString() {
+ return "line " + lineNumber;
+ }
+ public boolean equals(Object other) {
+ if (! (other instanceof LineNumberTag)) return false;
+ return lineNumber == ((LineNumberTag)other).lineNumber;
+ }
+ public int hashCode() {
+ return lineNumber;
+ }
+}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2002 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * PARC initial implementation
+ * Andy Clement pushed down into bcel module
+ * ******************************************************************/
+
+
+package org.aspectj.apache.bcel.generic;
+
+public final class LocalVariableTag extends Tag {
+ private Type type; // not always known, in which case signature has to be used
+ private final String signature;
+ private final String name;
+ private int slot;
+ private final int startPos;
+ boolean remapped = false;
+
+ // AMC - pr101047, two local vars with the same name can share the same slot, but must in that case
+ // have different start positions.
+ public LocalVariableTag(String sig, String name, int slot, int startPosition) {
+ this.signature = sig;
+ this.name = name;
+ this.slot = slot;
+ this.startPos = startPosition;
+ }
+
+ public LocalVariableTag(Type t,String sig, String name, int slot, int startPosition) {
+ this.type = t;
+ this.signature = sig;
+ this.name = name;
+ this.slot = slot;
+ this.startPos = startPosition;
+ }
+
+
+ public String getName() {return name;}
+ public int getSlot() {return slot;}
+ public String getType() {return signature;}
+ public Type getRealType() {return type;}
+
+ public void updateSlot(int newSlot) {
+ this.slot = newSlot;
+ this.remapped = true;
+ }
+
+ public boolean isRemapped() { return this.remapped; }
+
+ // ---- from Object
+
+ public String toString() {
+ return "local " + slot + ": " + signature + " " + name;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof LocalVariableTag)) return false;
+ LocalVariableTag o = (LocalVariableTag)other;
+ return o.slot == slot && o.startPos == startPos && o.signature.equals(signature) && o.name.equals(name);
+ }
+
+ private int hashCode = 0;
+ public int hashCode() {
+ if (hashCode == 0) {
+ int ret = 17;
+ ret = 37*ret + signature.hashCode();
+ ret = 37*ret + name.hashCode();
+ ret = 37*ret + slot;
+ ret = 37*ret + startPos;
+ hashCode = ret;
+ }
+ return hashCode;
+ }
+}
* use the `removeNOPs' method to get rid off them.
* The resulting method object can be obtained via the `getMethod()' method.
*
- * @version $Id: MethodGen.java,v 1.6 2006/02/14 13:32:07 aclement Exp $
+ * @version $Id: MethodGen.java,v 1.7 2006/02/21 10:49:15 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @author <A HREF="http://www.vmeng.com/beard">Patrick C. Beard</A> [setMaxStack()]
* @see InstructionList
private int max_stack;
private InstructionList il;
private boolean strip_attributes;
+ private int highestLineNumber = 0;
private ArrayList variable_vec = new ArrayList();
private ArrayList line_number_vec = new ArrayList();
}
}
}
+
+ public int getHighestlinenumber() { return highestLineNumber; }
/**
* Instantiate from existing method.
*/
public MethodGen(Method m, String class_name, ConstantPoolGen cp) {
+ this(m,class_name,cp,false);
+ }
+
+ public MethodGen(Method m, String class_name, ConstantPoolGen cp,boolean useTags) {
this(
m.getAccessFlags(),
if (a instanceof LineNumberTable) {
LineNumber[] ln = ((LineNumberTable) a).getLineNumberTable();
-
- for (int k = 0; k < ln.length; k++) {
- LineNumber l = ln[k];
- addLineNumber(il.findHandle(l.getStartPC(),arrayOfInstructions),
- l.getLineNumber());
+ if (useTags) {
+ // abracadabra, lets create tags rather than linenumbergens.
+ for (int k = 0; k < ln.length; k++) {
+ LineNumber l = ln[k];
+ int lnum = l.getLineNumber();
+ if (lnum>highestLineNumber) highestLineNumber=lnum;
+ LineNumberTag lt = new LineNumberTag(lnum);
+ il.findHandle(l.getStartPC(),arrayOfInstructions).addTargeter(lt);
+ }
+ } else {
+ for (int k = 0; k < ln.length; k++) {
+ LineNumber l = ln[k];
+ addLineNumber(il.findHandle(l.getStartPC(),arrayOfInstructions),
+ l.getLineNumber());
+ }
}
} else if (a instanceof LocalVariableTable) {
- LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable();
-
- removeLocalVariables();
-
- for (int k = 0; k < lv.length; k++) {
- LocalVariable l = lv[k];
- InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions);
- InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength(), arrayOfInstructions);
- // AMC, this actually gives us the first instruction AFTER the range,
- // so move back one... (findHandle can't cope with mid-instruction indices)
- if (end != null) end = end.getPrev();
- // Repair malformed handles
- if (null == start) start = il.getStart();
- if (null == end) end = il.getEnd();
-
- addLocalVariable(l.getName(), Type.getType(l.getSignature()), l.getIndex(), start, end);
+
+ // Lets have a go at creating Tags directly
+ if (useTags) {
+ LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable();
+
+ for (int k = 0; k < lv.length; k++) {
+ LocalVariable l = lv[k];
+ Type t = Type.getType(l.getSignature());
+ LocalVariableTag lvt = new LocalVariableTag(t,l.getSignature(),l.getName(),l.getIndex(),l.getStartPC());
+ InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions);
+ byte b = t.getType();
+ if (b!= Constants.T_ADDRESS) {
+ int increment = t.getSize();
+ if (l.getIndex()+increment>max_locals) max_locals = l.getIndex()+increment;
+ }
+ int end = l.getStartPC()+l.getLength();
+ do {
+ start.addTargeter(lvt);
+ start = start.getNext();
+ } while (start!=null && start.getPosition()<end);
+ }
+ } else {
+
+ LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable();
+
+ removeLocalVariables();
+
+ for (int k = 0; k < lv.length; k++) {
+ LocalVariable l = lv[k];
+ InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions);
+ InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength(), arrayOfInstructions);
+ // AMC, this actually gives us the first instruction AFTER the range,
+ // so move back one... (findHandle can't cope with mid-instruction indices)
+ if (end != null) end = end.getPrev();
+ // Repair malformed handles
+ if (null == start) start = il.getStart();
+ if (null == end) end = il.getEnd();
+
+ addLocalVariable(l.getName(), Type.getType(l.getSignature()), l.getIndex(), start, end);
+ }
}
} else addCodeAttribute(a);
}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2002 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * PARC initial implementation
+ * Andy Clement pushed down into bcel module
+ * ******************************************************************/
+
+
+package org.aspectj.apache.bcel.generic;
+
+
+/** A tag is an instruction-targeter that doesn't bother remembering its target(s) */
+public abstract class Tag implements InstructionTargeter, Cloneable {
+
+ public Tag() {
+ }
+
+ // ---- from InstructionTargeter
+ public boolean containsTarget(InstructionHandle ih) {
+ return false;
+ }
+
+ public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
+ old_ih.removeTargeter(this);
+ if (new_ih != null)
+ new_ih.addTargeter(this);
+ }
+
+ public Tag copy() {
+ try {
+ return (Tag)clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException("Sanity check, can't clone me");
+ }
+ }
+}
import org.aspectj.apache.bcel.generic.RET;
import org.aspectj.apache.bcel.generic.ReturnInstruction;
import org.aspectj.apache.bcel.generic.Select;
+import org.aspectj.apache.bcel.generic.Tag;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
import org.aspectj.bridge.IMessage;
Annotation a = decaM.getAnnotationX().getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true);
Method oldMethod = mg.getMethod();
- MethodGen myGen = new MethodGen(oldMethod,clazz.getClassName(),clazz.getConstantPoolGen());
+ MethodGen myGen = new MethodGen(oldMethod,clazz.getClassName(),clazz.getConstantPoolGen(),false);// dont use tags, they won't get repaired like for woven methods.
myGen.addAnnotation(ag);
Method newMethod = myGen.getMethod();
mg.addAnnotation(decaM.getAnnotationX());
import org.aspectj.apache.bcel.generic.InstructionTargeter;
import org.aspectj.apache.bcel.generic.InvokeInstruction;
import org.aspectj.apache.bcel.generic.LoadInstruction;
+import org.aspectj.apache.bcel.generic.LocalVariableTag;
import org.aspectj.apache.bcel.generic.MULTIANEWARRAY;
import org.aspectj.apache.bcel.generic.NEW;
import org.aspectj.apache.bcel.generic.ObjectType;
*/
public UnresolvedType ensureTargetTypeIsCorrect(UnresolvedType tx) {
-
- if (tx.equals(ResolvedType.OBJECT) && getKind() == MethodCall &&
- getSignature().getReturnType().equals(ResolvedType.OBJECT) &&
- getSignature().getArity()==0 &&
- getSignature().getName().charAt(0) == 'c' &&
- getSignature().getName().equals("clone")) {
+ Member msig = getSignature();
+ if (msig.getArity()==0 &&
+ getKind() == MethodCall &&
+ msig.getName().charAt(0) == 'c' &&
+ tx.equals(ResolvedType.OBJECT) &&
+ msig.getReturnType().equals(ResolvedType.OBJECT) &&
+ msig.getName().equals("clone")) {
// Lets go back through the code from the start of the shadow
InstructionHandle searchPtr = range.getStart().getPrev();
LoadInstruction li = (LoadInstruction)searchPtr.getInstruction();
li.getIndex();
LocalVariableTag lvt = LazyMethodGen.getLocalVariableTag(searchPtr,li.getIndex());
- if (lvt!=null) return lvt.getType();
+ if (lvt!=null) return UnresolvedType.forSignature(lvt.getType());
}
// A field access instruction may tell us the real type of what the clone() call is on
if (searchPtr.getInstruction() instanceof FieldInstruction) {
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InstructionTargeter;
import org.aspectj.apache.bcel.generic.LineNumberGen;
+import org.aspectj.apache.bcel.generic.LineNumberTag;
import org.aspectj.apache.bcel.generic.LocalVariableGen;
import org.aspectj.apache.bcel.generic.LocalVariableInstruction;
+import org.aspectj.apache.bcel.generic.LocalVariableTag;
import org.aspectj.apache.bcel.generic.MethodGen;
import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.apache.bcel.generic.Select;
+import org.aspectj.apache.bcel.generic.Tag;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.MessageUtil;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
private BcelMethod memberView;
private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
int highestLineNumber = 0;
+
+
+ /*
+ * This option specifies whether we let the BCEL classes create LineNumberGens and LocalVariableGens
+ * or if we make it create LineNumberTags and LocalVariableTags. Up until 1.5.1 we always created
+ * Gens - then on return from the MethodGen ctor we took them apart, reprocessed them all and
+ * created Tags. (see unpackLocals/unpackLineNumbers). As we have our own copy of Bcel, why not create
+ * the right thing straightaway? So setting this to true will call the MethodGen ctor() in such
+ * a way that it creates Tags - removing the need for unpackLocals/unpackLineNumbers - HOWEVER see
+ * the ensureAllLineNumberSetup() method for some other relevant info.
+ *
+ * Whats the difference between a Tag and a Gen? A Tag is more lightweight, it doesn't know which
+ * instructions it targets, it relies on the instructions targetting *it* - this reduces the amount
+ * of targeter manipulation we have to do.
+ *
+ * Because this *could* go wrong - it passes all our tests, but you never know, the option:
+ * -Xset:optimizeWithTags=false
+ * will turn it *OFF*
+ */
+ public static boolean avoidUseOfBcelGenObjects = true;
+ public static boolean checkedXsetOption = false;
/** This is nonnull if this method is the result of an "inlining". We currently
* copy methods into other classes for around advice. We add this field so
private void initialize() {
if (returnType != null) return;
+ // Check whether we need to configure the optimization
+ if (!checkedXsetOption) {
+ Properties p = enclosingClass.getWorld().getExtraConfiguration();
+ if (p!=null) {
+ avoidUseOfBcelGenObjects = Boolean.parseBoolean(p.getProperty("optimizeWithTags","true"));
+ if (!avoidUseOfBcelGenObjects)
+ enclosingClass.getWorld().getMessageHandler().handleMessage(MessageUtil.info("[optimizeWithTags=false] Disabling optimization to use Tags rather than Gens"));
+ }
+ checkedXsetOption=true;
+ }
+
//System.err.println("initializing: " + getName() + ", " + enclosingClass.getName() + ", " + returnType + ", " + savedMethod);
- MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPoolGen());
+ MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPoolGen(),avoidUseOfBcelGenObjects);
this.returnType = gen.getReturnType();
this.argumentTypes = gen.getArgumentTypes();
} else {
//body = new InstructionList(savedMethod.getCode().getCode());
body = gen.getInstructionList();
-
+
unpackHandlers(gen);
- unpackLineNumbers(gen);
- unpackLocals(gen);
+
+ if (avoidUseOfBcelGenObjects) {
+ ensureAllLineNumberSetup(gen);
+ highestLineNumber = gen.getHighestlinenumber();
+ } else {
+ unpackLineNumbers(gen);
+ unpackLocals(gen);
+ }
}
assertGoodBody();
gen.removeLineNumbers();
}
+ /**
+ * On entry to this method we have a method whose instruction stream contains a few instructions
+ * that have line numbers assigned to them (LineNumberTags). The aim is to ensure every instruction
+ * has the right line number. This is necessary because some of them may be extracted out into other
+ * methods - and it'd be useful for them to maintain the source line number for debugging.
+ */
+ private void ensureAllLineNumberSetup(MethodGen gen) {
+ LineNumberTag lr = null;
+ boolean skip = false;
+ for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
+ InstructionTargeter[] targeters = ih.getTargeters();
+ skip = false;
+ if (targeters != null) {
+ for (int i = targeters.length - 1; i >= 0; i--) {
+ InstructionTargeter targeter = targeters[i];
+ if (targeter instanceof LineNumberTag) {
+ lr = (LineNumberTag) targeter;
+ skip=true;
+ }
+ }
+ }
+ if (lr != null && !skip) {
+ ih.addTargeter(lr);
+ }
+ }
+ }
+
private void unpackLocals(MethodGen gen) {
Set locals = new HashSet();
for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
InstructionTargeter targeter = targeters[i];
if (targeter instanceof LocalVariableGen) {
LocalVariableGen lng = (LocalVariableGen) targeter;
- LocalVariableTag lr = new LocalVariableTag(BcelWorld.fromBcel(lng.getType()), lng.getName(), lng.getIndex(), lng.getStart().getPosition());
+ LocalVariableTag lr = new LocalVariableTag(lng.getType().getSignature()/*BcelWorld.fromBcel(lng.getType())*/, lng.getName(), lng.getIndex(), lng.getStart().getPosition());
if (lng.getStart() == ih) {
locals.add(lr);
} else {
continue;
}
slots.add(new Integer(tag.getSlot()));
-
- gen.addLocalVariable(tag.getName(),
- BcelWorld.makeBcelType(tag.getType()),
+ Type t = tag.getRealType();
+ if (t==null) {
+ t = BcelWorld.makeBcelType(UnresolvedType.forSignature(tag.getType()));
+ }
+ gen.addLocalVariable(
+ tag.getName(),
+ t,
tag.getSlot(),(InstructionHandle) start,(InstructionHandle) lvpos.end);
}
}
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Common Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- * PARC initial implementation
- * ******************************************************************/
-
-
-package org.aspectj.weaver.bcel;
-
-/** we don't actually target instructions, but instructions target us. */
-public class LineNumberTag extends Tag {
-
- private final int lineNumber;
-
- public LineNumberTag(int lineNumber) {
- this.lineNumber = lineNumber;
- }
-
- public int getLineNumber() { return lineNumber; }
-
- // ---- from Object
-
- public String toString() {
- return "line " + lineNumber;
- }
- public boolean equals(Object other) {
- if (! (other instanceof LineNumberTag)) return false;
- return lineNumber == ((LineNumberTag)other).lineNumber;
- }
- public int hashCode() {
- return lineNumber;
- }
-}
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Common Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- * PARC initial implementation
- * ******************************************************************/
-
-
-package org.aspectj.weaver.bcel;
-
-import org.aspectj.weaver.UnresolvedType;
-
-public final class LocalVariableTag extends Tag {
- private final UnresolvedType type;
- private final String name;
- private int slot;
- private final int startPos;
- boolean remapped = false;
-
- // AMC - pr101047, two local vars with the same name can share the same slot, but must in that case
- // have different start positions.
- public LocalVariableTag(UnresolvedType type, String name, int slot, int startPosition) {
- this.type = type;
- this.name = name;
- this.slot = slot;
- this.startPos = startPosition;
- }
-
- public String getName() {
- return name;
- }
- public int getSlot() {
- return slot;
- }
- public UnresolvedType getType() {
- return type;
- }
-
- public void updateSlot(int newSlot) {
- this.slot = newSlot;
- this.remapped = true;
- }
-
- public boolean isRemapped() { return this.remapped; }
-
- // ---- from Object
-
- public String toString() {
- return "local " + slot + ": " + type + " " + name;
- }
- public boolean equals(Object other) {
- if (!(other instanceof LocalVariableTag)) return false;
- LocalVariableTag o = (LocalVariableTag)other;
- return o.type.equals(type) && o.name.equals(name) && o.slot == slot && o.startPos == startPos;
- }
- private volatile int hashCode = 0;
- public int hashCode() {
- if (hashCode == 0) {
- int ret = 17;
- ret = 37*ret + type.hashCode();
- ret = 37*ret + name.hashCode();
- ret = 37*ret + slot;
- ret = 37*ret + startPos;
- hashCode = ret;
- }
- return hashCode;
- }
-}
// assert isRangeHandle(ih)
Range ret = null;
InstructionTargeter[] targeters = ih.getTargeters();
+ if (targeters!=null) {
for (int i = targeters.length - 1; i >= 0; i--) {
if (targeters[i] instanceof Range) {
Range r = (Range) targeters[i];
ret = (Range) targeters[i];
}
}
- if (ret == null) throw new BCException("shouldn't happen");
+ }
+ if (ret == null) {
+ throw new BCException("shouldn't happen");
+ }
return ret;
}
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InstructionTargeter;
import org.aspectj.apache.bcel.generic.LocalVariableInstruction;
+import org.aspectj.apache.bcel.generic.LocalVariableTag;
import org.aspectj.apache.bcel.generic.RET;
import org.aspectj.apache.bcel.generic.Select;
import org.aspectj.apache.bcel.generic.TargetLostException;
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Common Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- * PARC initial implementation
- * ******************************************************************/
-
-
-package org.aspectj.weaver.bcel;
-
-import org.aspectj.apache.bcel.generic.InstructionHandle;
-import org.aspectj.apache.bcel.generic.InstructionTargeter;
-
-/** A tag is an instruction-targeter that doesn't bother remembering its target(s) */
-abstract class Tag implements InstructionTargeter, Cloneable {
-
- public Tag() {
- }
-
- // ---- from InstructionTargeter
- public boolean containsTarget(InstructionHandle ih) {
- return false;
- }
-
- public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
- old_ih.removeTargeter(this);
- if (new_ih != null)
- new_ih.addTargeter(this);
- }
-
- public Tag copy() {
- try {
- return (Tag)clone();
- } catch (CloneNotSupportedException e) {
- throw new RuntimeException("Sanity check, can't clone me");
- }
- }
-}
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InstructionTargeter;
import org.aspectj.apache.bcel.generic.LDC;
+import org.aspectj.apache.bcel.generic.LineNumberTag;
import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.apache.bcel.generic.ReferenceType;
import org.aspectj.apache.bcel.generic.SIPUSH;
// }
// return getSourceLine(ih.getNext());
// }
-
- public static int getSourceLine(InstructionHandle ih) {
+ public static int getSourceLine(InstructionHandle ih) {//,boolean goforwards) {
int lookahead=0;
// arbitrary rule that we will never lookahead more than 100 instructions for a line #
while (lookahead++ < 100) {
}
}
}
- ih = ih.getNext();
+// if (goforwards) ih=ih.getNext(); else
+ ih=ih.getPrev();
}
//System.err.println("no line information available for: " + ih);
return -1;
}
+
+// public static int getSourceLine(InstructionHandle ih) {
+// return getSourceLine(ih,false);
+// }
// assumes that there is no already extant source line tag. Otherwise we'll have to be better.
public static void setSourceLine(InstructionHandle ih, int lineNumber) {