Commit 79e85263 authored by Yudi Zheng's avatar Yudi Zheng

Introduce @SyntheticStaticField

parent 6df8849c
......@@ -35,6 +35,7 @@ import ch.usi.dag.disl.exception.TransformerException;
import ch.usi.dag.disl.exclusion.ExclusionSet;
import ch.usi.dag.disl.guard.GuardHelper;
import ch.usi.dag.disl.localvar.SyntheticLocalVar;
import ch.usi.dag.disl.localvar.SyntheticStaticFieldVar;
import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.processor.Proc;
import ch.usi.dag.disl.processor.generator.PIResolver;
......@@ -80,6 +81,8 @@ public class DiSL {
private final Set<Scope> exclusionSet;
private final List<Snippet> snippets;
private final List<SyntheticStaticFieldVar> syntheticStaticFields;
/**
* DiSL initialization
......@@ -142,6 +145,10 @@ public class DiSL {
// - this is set when everything is ok
// - it serves as initialization flag
snippets = parsedSnippets;
// get parsed synthetic static fields
syntheticStaticFields = new LinkedList<SyntheticStaticFieldVar>(parser
.getAllLocalVars().getSyntheticStaticFields().values());
// TODO put checker here
// like After should catch normal and abnormal execution
......@@ -309,8 +316,8 @@ public class DiSL {
// *** viewing ***
Weaver.instrument(classNode, methodNode, snippetMarkings,
new LinkedList<SyntheticLocalVar>(usedSLVs), staticInfo,
piResolver);
new LinkedList<SyntheticLocalVar>(usedSLVs),
syntheticStaticFields, staticInfo, piResolver);
if(debug) {
System.out.println("Instumenting method: " + className
......
package ch.usi.dag.disl.annotation;
public @interface SyntheticStaticField {
public enum Scope {
PERCLASS, PERMETHOD
}
Scope scope() default (Scope.PERMETHOD);
}
......@@ -18,9 +18,11 @@ import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.analysis.Frame;
import org.objectweb.asm.tree.analysis.SourceValue;
import ch.usi.dag.disl.annotation.SyntheticStaticField;
import ch.usi.dag.disl.annotation.SyntheticLocal;
import ch.usi.dag.disl.exception.ParserException;
import ch.usi.dag.disl.localvar.LocalVars;
import ch.usi.dag.disl.localvar.SyntheticStaticFieldVar;
import ch.usi.dag.disl.localvar.SyntheticLocalVar;
import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.util.AsmHelper;
......@@ -118,6 +120,15 @@ abstract class AbstractParser {
continue;
}
// static local
if (annotationType.equals(Type.getType(SyntheticStaticField.class))) {
SyntheticStaticFieldVar slv = parseSyntheticStaticField(
className, field, annotation);
result.getSyntheticStaticFields().put(slv.getID(), slv);
continue;
}
throw new ParserException("Field " + className + "."
+ field.name + " has unsupported DiSL annotation");
}
......@@ -371,4 +382,40 @@ abstract class AbstractParser {
}
}
}
private SyntheticStaticFieldVar parseSyntheticStaticField(String className,
FieldNode field, AnnotationNode annotation) throws ParserException {
// check if field is static
if ((field.access & Opcodes.ACC_STATIC) == 0) {
throw new ParserException("Field " + field.name + className + "."
+ " declared as SyntheticLocalField but is not static");
}
// parse annotation data
STLAnnotaionData slad = new STLAnnotaionData();
ParserHelper.parseAnnotation(slad, annotation);
SyntheticStaticField.Scope ssfScope = SyntheticStaticField.Scope.PERMETHOD;
if (slad.scope != null) {
// enum is converted to array
// - first value is class name
// - second value is value name
ssfScope = SyntheticStaticField.Scope.valueOf(slad.scope[1]);
}
// field type
Type fieldType = Type.getType(field.desc);
return new SyntheticStaticFieldVar(className, field.name, fieldType,
ssfScope, field.access);
}
private static class STLAnnotaionData {
public String[] scope = null;
}
}
......@@ -9,6 +9,8 @@ public class LocalVars {
new HashMap<String, SyntheticLocalVar>();
private Map<String, ThreadLocalVar> threadLocals =
new HashMap<String, ThreadLocalVar>();
private Map<String, SyntheticStaticFieldVar> syntheticStaticFields =
new HashMap<String, SyntheticStaticFieldVar>();
public Map<String, SyntheticLocalVar> getSyntheticLocals() {
return syntheticLocals;
......@@ -17,10 +19,15 @@ public class LocalVars {
public Map<String, ThreadLocalVar> getThreadLocals() {
return threadLocals;
}
public Map<String, SyntheticStaticFieldVar> getSyntheticStaticFields() {
return syntheticStaticFields;
}
public void putAll(LocalVars localVars) {
syntheticLocals.putAll(localVars.getSyntheticLocals());
threadLocals.putAll(localVars.getThreadLocals());
syntheticStaticFields.putAll(localVars.getSyntheticStaticFields());
}
}
package ch.usi.dag.disl.localvar;
import org.objectweb.asm.Type;
import ch.usi.dag.disl.annotation.SyntheticStaticField.Scope;
public class SyntheticStaticFieldVar extends AbstractLocalVar {
private int access;
private Scope scope;
public SyntheticStaticFieldVar(String className, String fieldName, Type type,
Scope scope, int access) {
super(className, fieldName, type);
this.scope = scope;
this.access = access;
}
public String getTypeAsDesc() {
return getType().getDescriptor();
}
public int getAccess() {
return access;
}
public Scope getScope() {
return scope;
}
}
......@@ -8,6 +8,7 @@ import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
......@@ -22,7 +23,9 @@ import ch.usi.dag.disl.annotation.AfterReturning;
import ch.usi.dag.disl.annotation.AfterThrowing;
import ch.usi.dag.disl.annotation.Before;
import ch.usi.dag.disl.annotation.SyntheticLocal.Initialize;
import ch.usi.dag.disl.annotation.SyntheticStaticField;
import ch.usi.dag.disl.exception.DynamicInfoException;
import ch.usi.dag.disl.localvar.SyntheticStaticFieldVar;
import ch.usi.dag.disl.localvar.SyntheticLocalVar;
import ch.usi.dag.disl.processor.generator.PIResolver;
import ch.usi.dag.disl.snippet.Shadow;
......@@ -150,6 +153,57 @@ public class Weaver {
methodNode.maxLocals += syntheticLocalVars.size();
}
private static void fixSyntheticStaticField(ClassNode clazz, MethodNode method,
List<SyntheticStaticFieldVar> syntheticStaticFieldVars) {
for (AbstractInsnNode instr : method.instructions.toArray()) {
int opcode = instr.getOpcode();
if (!(opcode == Opcodes.GETSTATIC)
&& !(opcode == Opcodes.PUTSTATIC)) {
continue;
}
FieldInsnNode field_instr = (FieldInsnNode) instr;
for (SyntheticStaticFieldVar var : syntheticStaticFieldVars) {
if (!field_instr.owner.equals(var.getOwner())
|| !field_instr.name.equals(var.getName())) {
continue;
}
field_instr.owner = clazz.name;
field_instr.name = "$DISL_" + field_instr.name;
if (var.getScope() == SyntheticStaticField.Scope.PERMETHOD) {
field_instr.name += clazz.methods.indexOf(method);
}
int count = 0;
for (FieldNode field : clazz.fields) {
if (field.name.equals(field_instr.name)) {
break;
}
count++;
}
if (count == clazz.fields.size()) {
clazz.fields.add(new FieldNode(var.getAccess(), field_instr.name,
field_instr.desc, null, null));
}
break;
}
}
}
// Return a successor label of weaving location corresponding to
// the input 'end'.
private static LabelNode getEndLabel(MethodNode methodNode,
......@@ -243,6 +297,7 @@ public class Weaver {
public static void instrument(ClassNode classNode, MethodNode methodNode,
Map<Snippet, List<Shadow>> snippetMarkings,
List<SyntheticLocalVar> syntheticLocalVars,
List<SyntheticStaticFieldVar> syntheticStaticFieldVars,
SCGenerator staticInfoHolder, PIResolver piResolver)
throws DynamicInfoException {
......@@ -315,6 +370,7 @@ public class Weaver {
}
static2Local(methodNode, syntheticLocalVars);
fixSyntheticStaticField(classNode, methodNode, syntheticStaticFieldVars);
AdvancedSorter.sort(methodNode);
}
......
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