From 4970c023fea320fba928c6348fb15ae8c7df5f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Marek?= Date: Thu, 23 Aug 2012 11:21:46 +0000 Subject: [PATCH] Ported changes from 566:568 --- .../dag/disl/test/staticfield/DiSLClass.java | 35 ++++++++++++ .../usi/dag/disl/test/staticfield/MANIFEST.MF | 2 + .../disl/test/staticfield/TargetClass.java | 12 ++++ src/ch/usi/dag/disl/DiSL.java | 11 +++- .../disl/annotation/SyntheticStaticField.java | 10 ++++ .../dag/disl/classparser/AbstractParser.java | 47 ++++++++++++++++ src/ch/usi/dag/disl/localvar/LocalVars.java | 7 +++ .../localvar/SyntheticStaticFieldVar.java | 32 +++++++++++ src/ch/usi/dag/disl/weaver/Weaver.java | 56 +++++++++++++++++++ 9 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 src-test/ch/usi/dag/disl/test/staticfield/DiSLClass.java create mode 100644 src-test/ch/usi/dag/disl/test/staticfield/MANIFEST.MF create mode 100644 src-test/ch/usi/dag/disl/test/staticfield/TargetClass.java create mode 100644 src/ch/usi/dag/disl/annotation/SyntheticStaticField.java create mode 100644 src/ch/usi/dag/disl/localvar/SyntheticStaticFieldVar.java diff --git a/src-test/ch/usi/dag/disl/test/staticfield/DiSLClass.java b/src-test/ch/usi/dag/disl/test/staticfield/DiSLClass.java new file mode 100644 index 00000000..a4737bf6 --- /dev/null +++ b/src-test/ch/usi/dag/disl/test/staticfield/DiSLClass.java @@ -0,0 +1,35 @@ +package ch.usi.dag.disl.test.staticfield; + +import ch.usi.dag.disl.annotation.AfterReturning; +import ch.usi.dag.disl.annotation.Before; +import ch.usi.dag.disl.annotation.SyntheticStaticField; +import ch.usi.dag.disl.annotation.SyntheticStaticField.Scope; +import ch.usi.dag.disl.marker.BodyMarker; +import ch.usi.dag.disl.staticcontext.MethodStaticContext; + +public class DiSLClass { + + @SyntheticStaticField(scope = Scope.PERCLASS) + public static String s; + + @SyntheticStaticField(scope = Scope.PERMETHOD) + public static String mid; + + @Before(marker = BodyMarker.class, scope = "TargetClass.*", order = 2) + public static void precondition(MethodStaticContext msc) { + + mid = msc.thisMethodFullName(); + System.out.println("Entering " + mid + " while s is " + s); + } + + @AfterReturning(marker = BodyMarker.class, scope = "TargetClass.*", order = 2) + public static void postcondition() { + System.out.println("Exiting " + mid + " while s is " + s); + } + + @Before(marker = BodyMarker.class, scope = "TargetClass.print", order = 1) + public static void precondition2() { + s = "Set in TargetClass.print"; + } + +} diff --git a/src-test/ch/usi/dag/disl/test/staticfield/MANIFEST.MF b/src-test/ch/usi/dag/disl/test/staticfield/MANIFEST.MF new file mode 100644 index 00000000..8036ea6a --- /dev/null +++ b/src-test/ch/usi/dag/disl/test/staticfield/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +DiSL-Classes: ch.usi.dag.disl.test.staticfield.DiSLClass \ No newline at end of file diff --git a/src-test/ch/usi/dag/disl/test/staticfield/TargetClass.java b/src-test/ch/usi/dag/disl/test/staticfield/TargetClass.java new file mode 100644 index 00000000..f34259fd --- /dev/null +++ b/src-test/ch/usi/dag/disl/test/staticfield/TargetClass.java @@ -0,0 +1,12 @@ +package ch.usi.dag.disl.test.staticfield; +public class TargetClass { + + public void print() { + System.out.println("This is the body of TargetClass.print"); + } + + public static void main(String[] args) { + TargetClass t = new TargetClass(); + t.print(); + } +} diff --git a/src/ch/usi/dag/disl/DiSL.java b/src/ch/usi/dag/disl/DiSL.java index 5ceacb6e..a3de277a 100644 --- a/src/ch/usi/dag/disl/DiSL.java +++ b/src/ch/usi/dag/disl/DiSL.java @@ -36,6 +36,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; @@ -81,6 +82,8 @@ public class DiSL { private final Set exclusionSet; private final List snippets; + + private final List syntheticStaticFields; /** * DiSL initialization @@ -143,6 +146,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(parser + .getAllLocalVars().getSyntheticStaticFields().values()); // TODO put checker here // like After should catch normal and abnormal execution @@ -315,8 +322,8 @@ public class DiSL { // *** viewing *** Weaver.instrument(classNode, methodNode, snippetMarkings, - new LinkedList(usedSLVs), staticInfo, - piResolver); + new LinkedList(usedSLVs), + syntheticStaticFields, staticInfo, piResolver); } return true; diff --git a/src/ch/usi/dag/disl/annotation/SyntheticStaticField.java b/src/ch/usi/dag/disl/annotation/SyntheticStaticField.java new file mode 100644 index 00000000..dc6f65ae --- /dev/null +++ b/src/ch/usi/dag/disl/annotation/SyntheticStaticField.java @@ -0,0 +1,10 @@ +package ch.usi.dag.disl.annotation; + +public @interface SyntheticStaticField { + + public enum Scope { + PERCLASS, PERMETHOD + } + + Scope scope() default (Scope.PERMETHOD); +} diff --git a/src/ch/usi/dag/disl/classparser/AbstractParser.java b/src/ch/usi/dag/disl/classparser/AbstractParser.java index 3dae7a5c..ac7ea874 100644 --- a/src/ch/usi/dag/disl/classparser/AbstractParser.java +++ b/src/ch/usi/dag/disl/classparser/AbstractParser.java @@ -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; + } + } diff --git a/src/ch/usi/dag/disl/localvar/LocalVars.java b/src/ch/usi/dag/disl/localvar/LocalVars.java index ae30dfdf..445e0a57 100644 --- a/src/ch/usi/dag/disl/localvar/LocalVars.java +++ b/src/ch/usi/dag/disl/localvar/LocalVars.java @@ -9,6 +9,8 @@ public class LocalVars { new HashMap(); private Map threadLocals = new HashMap(); + private Map syntheticStaticFields = + new HashMap(); public Map getSyntheticLocals() { return syntheticLocals; @@ -17,10 +19,15 @@ public class LocalVars { public Map getThreadLocals() { return threadLocals; } + + public Map getSyntheticStaticFields() { + return syntheticStaticFields; + } public void putAll(LocalVars localVars) { syntheticLocals.putAll(localVars.getSyntheticLocals()); threadLocals.putAll(localVars.getThreadLocals()); + syntheticStaticFields.putAll(localVars.getSyntheticStaticFields()); } } diff --git a/src/ch/usi/dag/disl/localvar/SyntheticStaticFieldVar.java b/src/ch/usi/dag/disl/localvar/SyntheticStaticFieldVar.java new file mode 100644 index 00000000..8ac14968 --- /dev/null +++ b/src/ch/usi/dag/disl/localvar/SyntheticStaticFieldVar.java @@ -0,0 +1,32 @@ +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; + } + +} diff --git a/src/ch/usi/dag/disl/weaver/Weaver.java b/src/ch/usi/dag/disl/weaver/Weaver.java index d0b068e7..9ee81a4a 100644 --- a/src/ch/usi/dag/disl/weaver/Weaver.java +++ b/src/ch/usi/dag/disl/weaver/Weaver.java @@ -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,8 +23,10 @@ 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.DynamicContextException; import ch.usi.dag.disl.localvar.SyntheticLocalVar; +import ch.usi.dag.disl.localvar.SyntheticStaticFieldVar; import ch.usi.dag.disl.processor.generator.PIResolver; import ch.usi.dag.disl.snippet.Shadow; import ch.usi.dag.disl.snippet.Snippet; @@ -150,6 +153,57 @@ public class Weaver { methodNode.maxLocals += syntheticLocalVars.size(); } + private static void fixSyntheticStaticField(ClassNode clazz, MethodNode method, + List 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> snippetMarkings, List syntheticLocalVars, + List syntheticStaticFieldVars, SCGenerator staticInfoHolder, PIResolver piResolver) throws DynamicContextException { @@ -315,6 +370,7 @@ public class Weaver { } static2Local(methodNode, syntheticLocalVars); + fixSyntheticStaticField(classNode, methodNode, syntheticStaticFieldVars); AdvancedSorter.sort(methodNode); } -- GitLab