Commit f9134799 authored by Lubomir Bulej's avatar Lubomir Bulej

Unified white space before subsequent merge.

parent 5f776067
......@@ -25,73 +25,73 @@ import ch.usi.dag.disl.snippet.Snippet;
public class ClassParser {
SnippetParser snippetParser = new SnippetParser();
ProcessorParser processorParser = new ProcessorParser();
public void parse(InputStream is) throws ParserException,
SnippetParserException, ReflectionException, ScopeParserException,
StaticContextGenException, ProcessorParserException,
MarkerException, GuardException {
// prepare class node
ClassReader cr;
try {
cr = new ClassReader(is);
} catch (IOException e) {
// rethrow exception as DiSL exception
throw new ParserException(e);
}
ClassNode classNode = new ClassNode();
cr.accept(classNode, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
// decide according to processor annotation if it is a snippet or
// processor
// *** snippet ***
if (classNode.invisibleAnnotations == null) {
snippetParser.parse(classNode);
return;
}
// *** processor ***
// check for one annotation
if (classNode.invisibleAnnotations.size() > 1) {
throw new ParserException("Class " + classNode.name
+ " may have only one anotation");
}
AnnotationNode annotation =
(AnnotationNode) classNode.invisibleAnnotations.get(0);
Type annotationType = Type.getType(annotation.desc);
// check for processor annotation
if (! annotationType.equals(Type.getType(ArgumentProcessor.class))) {
throw new ParserException("Class " + classNode.name
+ " may have only ArgumentProcessor anotation");
}
processorParser.parse(classNode);
}
public LocalVars getAllLocalVars() {
LocalVars merged = new LocalVars();
// merge local variables from snippets and processors
merged.putAll(snippetParser.getAllLocalVars());
merged.putAll(processorParser.getAllLocalVars());
return merged;
}
public List<Snippet> getSnippets() {
return snippetParser.getSnippets();
}
public Map<Type, Proc> getProcessors() {
return processorParser.getProcessors();
}
SnippetParser snippetParser = new SnippetParser();
ProcessorParser processorParser = new ProcessorParser();
public void parse(InputStream is) throws ParserException,
SnippetParserException, ReflectionException, ScopeParserException,
StaticContextGenException, ProcessorParserException,
MarkerException, GuardException {
// prepare class node
ClassReader cr;
try {
cr = new ClassReader(is);
} catch (IOException e) {
// rethrow exception as DiSL exception
throw new ParserException(e);
}
ClassNode classNode = new ClassNode();
cr.accept(classNode, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
// decide according to processor annotation if it is a snippet or
// processor
// *** snippet ***
if (classNode.invisibleAnnotations == null) {
snippetParser.parse(classNode);
return;
}
// *** processor ***
// check for one annotation
if (classNode.invisibleAnnotations.size() > 1) {
throw new ParserException("Class " + classNode.name
+ " may have only one anotation");
}
AnnotationNode annotation =
(AnnotationNode) classNode.invisibleAnnotations.get(0);
Type annotationType = Type.getType(annotation.desc);
// check for processor annotation
if (! annotationType.equals(Type.getType(ArgumentProcessor.class))) {
throw new ParserException("Class " + classNode.name
+ " may have only ArgumentProcessor anotation");
}
processorParser.parse(classNode);
}
public LocalVars getAllLocalVars() {
LocalVars merged = new LocalVars();
// merge local variables from snippets and processors
merged.putAll(snippetParser.getAllLocalVars());
merged.putAll(processorParser.getAllLocalVars());
return merged;
}
public List<Snippet> getSnippets() {
return snippetParser.getSnippets();
}
public Map<Type, Proc> getProcessors() {
return processorParser.getProcessors();
}
}
......@@ -19,103 +19,103 @@ import ch.usi.dag.disl.util.ReflectionHelper;
// package visible
abstract class ParserHelper {
public static Class<?> getGuard(Type guardType) throws ReflectionException {
if(guardType == null) {
return null;
}
return ReflectionHelper.resolveClass(guardType);
}
// NOTE: first parameter is modified by this function
public static <T> void parseAnnotation(T parsedDataObject,
AnnotationNode annotation) {
try {
// nothing to do
if(annotation.values == null) {
return;
}
Iterator<?> it = annotation.values.iterator();
while (it.hasNext()) {
// get attribute name
String name = (String) it.next();
// find correct field
Field attr = parsedDataObject.getClass().getField(name);
if (attr == null) {
throw new DiSLFatalException("Unknow attribute "
+ name
+ " in annotation "
+ Type.getType(annotation.desc).toString()
+ ". This may happen if annotation class is changed"
+ " but parser class is not.");
}
// set attribute value into the field
attr.set(parsedDataObject, it.next());
}
} catch (Exception e) {
throw new DiSLFatalException(
"Reflection error wihle parsing annotation", e);
}
}
public static void usesContextProperly(String className, String methodName,
String methodDescriptor, InsnList instructions)
throws ParserException {
Type[] types = Type.getArgumentTypes(methodDescriptor);
int maxArgIndex = 0;
// count the max index of arguments
for (int i = 0; i < types.length; i++) {
// add number of occupied slots
maxArgIndex += types[i].getSize();
}
// The following code assumes that all disl snippets are static
for (AbstractInsnNode instr : AsmHelper.allInsnsFrom (instructions)) {
switch (instr.getOpcode()) {
// test if the context is stored somewhere else
case Opcodes.ALOAD: {
int local = ((VarInsnNode) instr).var;
if (local < maxArgIndex
&& instr.getNext().getOpcode() == Opcodes.ASTORE) {
throw new ParserException("In method " + className
+ "." + methodName + " - method parameter"
+ " (context) cannot be stored into local"
+ " variable");
}
break;
}
// test if something is stored in the context
case Opcodes.ASTORE: {
int local = ((VarInsnNode) instr).var;
if (local < maxArgIndex) {
throw new ParserException("In method " + className
+ "." + methodName + " - method parameter"
+ " (context) cannot be overwritten");
}
break;
}
}
}
}
public static Class<?> getGuard(Type guardType) throws ReflectionException {
if(guardType == null) {
return null;
}
return ReflectionHelper.resolveClass(guardType);
}
// NOTE: first parameter is modified by this function
public static <T> void parseAnnotation(T parsedDataObject,
AnnotationNode annotation) {
try {
// nothing to do
if(annotation.values == null) {
return;
}
Iterator<?> it = annotation.values.iterator();
while (it.hasNext()) {
// get attribute name
String name = (String) it.next();
// find correct field
Field attr = parsedDataObject.getClass().getField(name);
if (attr == null) {
throw new DiSLFatalException("Unknow attribute "
+ name
+ " in annotation "
+ Type.getType(annotation.desc).toString()
+ ". This may happen if annotation class is changed"
+ " but parser class is not.");
}
// set attribute value into the field
attr.set(parsedDataObject, it.next());
}
} catch (Exception e) {
throw new DiSLFatalException(
"Reflection error wihle parsing annotation", e);
}
}
public static void usesContextProperly(String className, String methodName,
String methodDescriptor, InsnList instructions)
throws ParserException {
Type[] types = Type.getArgumentTypes(methodDescriptor);
int maxArgIndex = 0;
// count the max index of arguments
for (int i = 0; i < types.length; i++) {
// add number of occupied slots
maxArgIndex += types[i].getSize();
}
// The following code assumes that all disl snippets are static
for (AbstractInsnNode instr : AsmHelper.allInsnsFrom (instructions)) {
switch (instr.getOpcode()) {
// test if the context is stored somewhere else
case Opcodes.ALOAD: {
int local = ((VarInsnNode) instr).var;
if (local < maxArgIndex
&& instr.getNext().getOpcode() == Opcodes.ASTORE) {
throw new ParserException("In method " + className
+ "." + methodName + " - method parameter"
+ " (context) cannot be stored into local"
+ " variable");
}
break;
}
// test if something is stored in the context
case Opcodes.ASTORE: {
int local = ((VarInsnNode) instr).var;
if (local < maxArgIndex) {
throw new ParserException("In method " + className
+ "." + methodName + " - method parameter"
+ " (context) cannot be overwritten");
}
break;
}
}
}
}
}
package ch.usi.dag.disl.marker;
import java.util.LinkedList;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.snippet.Shadow.WeavingRegion;
import ch.usi.dag.disl.util.AsmHelper;
/**
* <p>
* Marks whole method body.
*
* <p>
* Sets the start at the beginning of a method and the end at the end of a
* method. If the method is a constructor, the start is inserted after the
* constructor invocation.
*/
// FIXME LB: For empty constructors, the order of After and Before snippets is
// reversed.
public class AfterInitBodyMarker extends AbstractMarker {
@Override
public List<MarkedRegion> mark(final MethodNode method) {
MarkedRegion region = new MarkedRegion(
AsmHelper.findFirstValidMark(method));
//
// Add all instructions preceding the RETURN instructions
// as marked region ends.
//
for (final AbstractInsnNode insn : AsmHelper.allInsnsFrom(method.instructions)) {
int opcode = insn.getOpcode();
if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) {
region.addEnd(insn.getPrevious());
}
}
WeavingRegion wr = region.computeDefaultWeavingRegion(method);
wr.setAfterThrowEnd(method.instructions.getLast());
region.setWeavingRegion(wr);
//
final List<MarkedRegion> result = new LinkedList<MarkedRegion>();
result.add(region);
return result;
}
}
package ch.usi.dag.disl.marker;
import java.util.LinkedList;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.snippet.Shadow.WeavingRegion;
import ch.usi.dag.disl.util.AsmHelper;
/**
* <p>
* Marks whole method body.
*
* <p>
* Sets the start at the beginning of a method and the end at the end of a
* method. If the method is a constructor, the start is inserted after the
* constructor invocation.
*/
// FIXME LB: For empty constructors, the order of After and Before snippets is
// reversed.
public class AfterInitBodyMarker extends AbstractMarker {
@Override
public List<MarkedRegion> mark(final MethodNode method) {
MarkedRegion region = new MarkedRegion(
AsmHelper.findFirstValidMark(method));
//
// Add all instructions preceding the RETURN instructions
// as marked region ends.
//
for (final AbstractInsnNode insn : AsmHelper.allInsnsFrom(method.instructions)) {
int opcode = insn.getOpcode();
if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) {
region.addEnd(insn.getPrevious());
}
}
WeavingRegion wr = region.computeDefaultWeavingRegion(method);
wr.setAfterThrowEnd(method.instructions.getLast());
region.setWeavingRegion(wr);
//
final List<MarkedRegion> result = new LinkedList<MarkedRegion>();
result.add(region);
return result;
}
}
package ch.usi.dag.disl.marker;
import java.util.LinkedList;
import java.util.List;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.BasicBlockCalc;
/**
* <p>
* Marks basic block.
*
* <p>
* Sets the start at the beginning of a basic block and the end at the end of a
* basic block. Considers only jump instructions, lookup switch and table
* switch.
*/
public class BasicBlockMarker extends AbstractDWRMarker {
protected boolean isPrecise = false;
@Override
public List<MarkedRegion> markWithDefaultWeavingReg(MethodNode methodNode) {
List<MarkedRegion> regions = new LinkedList<MarkedRegion>();
List<AbstractInsnNode> seperators = BasicBlockCalc.getAll(
methodNode.instructions, methodNode.tryCatchBlocks, isPrecise);
AbstractInsnNode last = AsmHelper.skipVirtualInsns(
methodNode.instructions.getLast(), false);
seperators.add(last);
for (int i = 0; i < seperators.size() - 1; i++) {
AbstractInsnNode start = seperators.get(i);
AbstractInsnNode end = seperators.get(i + 1);
if (i != seperators.size() - 2) {
end = end.getPrevious();
}
regions.add(new MarkedRegion(start, AsmHelper.skipVirtualInsns(end,
false)));
}
return regions;
}
}
package ch.usi.dag.disl.marker;
import java.util.LinkedList;
import java.util.List;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.BasicBlockCalc;
/**
* <p>
* Marks basic block.
*
* <p>
* Sets the start at the beginning of a basic block and the end at the end of a
* basic block. Considers only jump instructions, lookup switch and table
* switch.
*/
public class BasicBlockMarker extends AbstractDWRMarker {
protected boolean isPrecise = false;
@Override
public List<MarkedRegion> markWithDefaultWeavingReg(MethodNode methodNode) {
List<MarkedRegion> regions = new LinkedList<MarkedRegion>();
List<AbstractInsnNode> seperators = BasicBlockCalc.getAll(
methodNode.instructions, methodNode.tryCatchBlocks, isPrecise);
AbstractInsnNode last = AsmHelper.skipVirtualInsns(
methodNode.instructions.getLast(), false);
seperators.add(last);
for (int i = 0; i < seperators.size() - 1; i++) {
AbstractInsnNode start = seperators.get(i);
AbstractInsnNode end = seperators.get(i + 1);
if (i != seperators.size() - 2) {
end = end.getPrevious();
}
regions.add(new MarkedRegion(start, AsmHelper.skipVirtualInsns(end,
false)));
}
return regions;
}
}
package ch.usi.dag.disl.marker;
import java.util.LinkedList;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.snippet.Shadow.WeavingRegion;
import ch.usi.dag.disl.util.AsmHelper;
/**
* <p>
* Marks whole method body.
*
* <p>
* Sets the start at the beginning of a method and the end at the end of a
* method.
*/
public class BodyMarker extends AbstractMarker {
@Override
public List<MarkedRegion> mark(MethodNode method) {
List<MarkedRegion> regions = new LinkedList<MarkedRegion>();
MarkedRegion region =
new MarkedRegion(method.instructions.getFirst());
for (AbstractInsnNode instr : AsmHelper.allInsnsFrom(method.instructions)) {
int opcode = instr.getOpcode();
if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) {
region.addEnd(instr);
}
}
WeavingRegion wregion = region.computeDefaultWeavingRegion(method);
wregion.setAfterThrowEnd(method.instructions.getLast());
region.setWeavingRegion(wregion);
regions.add(region);
return regions;
}
}
package ch.usi.dag.disl.marker;
import java.util.LinkedList;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.snippet.Shadow.WeavingRegion;
import ch.usi.dag.disl.util.AsmHelper;
/**
* <p>
* Marks whole method body.
*
* <p>
* Sets the start at the beginning of a method and the end at the end of a
* method.
*/
public class BodyMarker extends AbstractMarker {
@Override
public List<MarkedRegion> mark(MethodNode method) {
List<MarkedRegion> regions = new LinkedList<MarkedRegion>();
MarkedRegion region =
new MarkedRegion(method.instructions.getFirst());
for (AbstractInsnNode instr : AsmHelper.allInsnsFrom(method.instructions)) {
int opcode = instr.getOpcode();
if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) {
region.addEnd(instr);
}
}
WeavingRegion wregion = region.computeDefaultWeavingRegion(method);
wregion.setAfterThrowEnd(method.instructions.getLast());
region.setWeavingRegion(wregion);
regions.add(region);
return regions;
}
}
package ch.usi.dag.disl.marker;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.exception.MarkerException;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmOpcodes;
/**
* <p>
* Marks one java bytecode instruction.
*
* <p>
* Sets the start before a bytecode instruction and the end after a bytecode
* instruction. If the bytecode instruction is (conditional) jump the end is
* also inserted before the instruction (preserves before-after semantics).
*/
public class BytecodeMarker extends AbstractDWRMarker {
protected static final String INSTR_DELIM = ",";
protected Set<Integer> searchedInstrNums = new HashSet<Integer>();
public BytecodeMarker(Parameter param) throws MarkerException {
// set delim for instruction list
param.setMultipleValDelim(INSTR_DELIM);
// translate all instructions to opcodes
for (String instr : param.getMultipleValues()) {
try {