Commit 40851462 authored by Lubomir Bulej's avatar Lubomir Bulej

AbstractLocalVar, Scope: cosmetic changes in the javadoc comments.

AsmHelper: added method asList(InsnList) for converting InsnList into a List<AbstractInsnNode>
AsmHelper: added a few more helper methods needed for subsequent changes.
parent d2557e0f
......@@ -3,7 +3,7 @@ package ch.usi.dag.disl.localvar;
import org.objectweb.asm.Type;
abstract class AbstractLocalVar {
public abstract class AbstractLocalVar {
private final static String NAME_DELIM = ".";
......@@ -47,11 +47,11 @@ abstract class AbstractLocalVar {
//
/**
* Returns a fully qualified field name for the given class name
* Returns a fully qualified internal field name for the given class name
* and field name.
*
* @param ownerClassName
* name of the field owner class
* internal name of the field owner class
* @param fieldName
* name of the field within the class
*
......
......@@ -7,13 +7,15 @@ package ch.usi.dag.disl.scope;
public interface Scope {
/**
* Determines whether this scope matches the given class name, method name,
* and method type descriptor.
*
* @param className standard or internal name of the class to match
* @param methodName name of the method to match
* @param methodDesc type descriptor of the method to match
* Determines whether this scope matches the given class name (including
* package name), method name, and method type descriptor.
*
* @param className
* standard or internal name of the class to match
* @param methodName
* name of the method to match
* @param methodDesc
* type descriptor of the method to match
* @return {@code true} if the scope matches the given class name, method
* name, and method type descriptor, {@code false} otherwise.
*/
......
......@@ -2,6 +2,9 @@ package ch.usi.dag.disl.util;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
......@@ -9,6 +12,7 @@ import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
......@@ -300,6 +304,13 @@ public abstract class AsmHelper {
return getField (owner.getInternalName (), name, desc.getDescriptor ());
}
public static FieldInsnNode getField (
final Type ownerType, final String name, final String desc
) {
return getField (ownerType.getInternalName (), name, desc);
}
public static FieldInsnNode getField (
final String owner, final String name, final String desc
) {
......@@ -307,6 +318,13 @@ public abstract class AsmHelper {
}
public static FieldInsnNode putField (
final Type ownerType, final String name, final String desc
) {
return putField (ownerType.getInternalName (), name, desc);
}
public static FieldInsnNode putField (
final String owner, final String name, final String desc
) {
......@@ -459,6 +477,7 @@ public abstract class AsmHelper {
return result;
}
public static final class ClonedCode {
private final InsnList __instructions;
private final List <TryCatchBlockNode> __tryCatchBlocks;
......@@ -736,6 +755,205 @@ public abstract class AsmHelper {
};
}
/**
* Wraps an {@link InsnList} into a {@link List} instance to enable
* stream processing.
*
* @param insns
* the {@link InsnList} to wrap
* @return an instance of {@link List} wrapping the given
* {@link InsnList}
*/
public static List <AbstractInsnNode> asList (final InsnList insns) {
return new AbstractList <AbstractInsnNode> () {
@Override
public int size () {
return insns.size ();
}
//
// Each AbstractInsnNode instance is considered unique
// and cannot be part of multiple lists. Therefore if an
// instruction appears in a list, it is its first as well
// the last occurrence.
//
@Override
public boolean contains (final Object obj) {
if (obj instanceof AbstractInsnNode) {
return insns.contains ((AbstractInsnNode) obj);
} else {
return false;
}
}
@Override
public int indexOf (final Object obj) {
return __indexOf (insns, obj);
}
@Override
public int lastIndexOf (final Object obj) {
return __indexOf (insns, obj);
}
private int __indexOf (final InsnList insns, final Object obj) {
if (obj instanceof AbstractInsnNode) {
return insns.indexOf ((AbstractInsnNode) obj);
} else {
return -1;
}
}
//
@Override
public AbstractInsnNode [] toArray () {
return insns.toArray ();
}
@Override
public <T> T [] toArray (final T [] output) {
//
// The following cast may fail, if the target type
// is not a super-type of AbstractInsnNode [].
//
@SuppressWarnings ("unchecked")
final T [] nodes = (T []) insns.toArray ();
if (output.length < nodes.length) {
return nodes;
} else {
System.arraycopy (nodes, 0, output, 0, nodes.length);
if (output.length > nodes.length) {
Arrays.fill (output, nodes.length, output.length, null);
}
return output;
}
}
//
@Override
public boolean add (final AbstractInsnNode insn) {
__ensureValidInsn (insn);
insns.add (insn);
return true;
}
@Override
public void add (final int index, final AbstractInsnNode insn) {
__ensureValidInsn (insn);
insns.insertBefore (insns.get (index), insn);
}
@Override
public boolean addAll (
final int index, final Collection <? extends AbstractInsnNode> c
) {
final int sizeBefore = insns.size ();
final AbstractInsnNode oldInsn = insns.get (index);
for (final AbstractInsnNode insn : c) {
__ensureValidInsn (insn);
insns.insertBefore (oldInsn, insn);
}
return sizeBefore != insns.size ();
}
private void __ensureValidInsn (final AbstractInsnNode insn) {
//
// Make sure the instruction is not null and does not
// belong to any other instruction list.
//
Objects.requireNonNull (insn, "insn cannot be <null>");
__ensureFreeStandingInsn (insn);
}
private void __ensureFreeStandingInsn (final AbstractInsnNode insn) {
if (insn.getPrevious () != null || insn.getNext () != null) {
throw new IllegalArgumentException ("cannot add instruction already belonging to a list");
}
}
//
@Override
public boolean remove (final Object obj) {
if (obj instanceof AbstractInsnNode) {
//
// Make sure the instruction belongs to this list.
//
final AbstractInsnNode insn = (AbstractInsnNode) obj;
if (insns.contains (insn)) {
insns.remove (insn);
return true;
} else {
throw new IllegalArgumentException ("cannot remove instruction not belonging to the list");
}
}
return false;
}
@Override
public AbstractInsnNode remove (final int index) {
final AbstractInsnNode oldInsn = insns.get (index);
insns.remove (oldInsn);
return oldInsn;
}
@Override
public void clear () {
insns.clear ();
}
//
@Override
public AbstractInsnNode get (final int index) {
return insns.get (index);
}
@Override
public AbstractInsnNode set (final int index, final AbstractInsnNode insn) {
__ensureValidInsn (insn);
final AbstractInsnNode oldInsn = insns.get (index);
insns.set (oldInsn, insn);
return oldInsn;
}
//
@Override
public Iterator <AbstractInsnNode> iterator () {
return listIterator ();
}
@Override
public ListIterator <AbstractInsnNode> listIterator (final int index) {
return insns.iterator (index);
}
};
}
}
//
......@@ -747,6 +965,10 @@ public abstract class AsmHelper {
}
public static boolean isStaticFieldAccess (final AbstractInsnNode node) {
return isStaticFieldAccess (node.getOpcode ());
}
public static boolean isStaticFieldAccess (final int opcode) {
return opcode == Opcodes.GETSTATIC || opcode == Opcodes.PUTSTATIC;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment