diff graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java @ 18485:e3c95cbbb50c

Truffle Instrumentation: major API revision, based around the Probe and Instrument classes; add Instrumentable API for language implementors, with most details automated; reimplemented to handle AST splitting automatically; more JUnit tests.
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Sun, 23 Nov 2014 16:07:23 -0800
parents dc2e000bed40
children 128586040207
line wrap: on
line diff
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java	Fri Nov 21 13:16:02 2014 +0100
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java	Sun Nov 23 16:07:23 2014 -0800
@@ -36,10 +36,14 @@
 import org.junit.runners.*;
 import org.junit.runners.model.*;
 
-import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.instrument.*;
+import com.oracle.truffle.api.instrument.impl.*;
+import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.source.*;
+import com.oracle.truffle.sl.factory.*;
 import com.oracle.truffle.sl.nodes.instrument.*;
+import com.oracle.truffle.sl.nodes.local.*;
 import com.oracle.truffle.sl.parser.*;
 import com.oracle.truffle.sl.runtime.*;
 import com.oracle.truffle.sl.test.instrument.SLInstrumentTestRunner.InstrumentTestCase;
@@ -85,10 +89,14 @@
 
     public SLInstrumentTestRunner(Class<?> testClass) throws InitializationError {
         super(testClass);
+        final SLStandardASTProber prober = new SLStandardASTProber();
+        Probe.registerASTProber(prober);
         try {
             testCases = createTests(testClass);
         } catch (IOException e) {
             throw new InitializationError(e);
+        } finally {
+            Probe.unregisterASTProber(prober);
         }
     }
 
@@ -197,33 +205,21 @@
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         PrintStream printer = new PrintStream(out);
+        final ASTProber prober = new SLStandardASTProber();
+        Probe.registerASTProber(prober);
         try {
             // We use the name of the file to determine what visitor to attach to it.
             if (testCase.baseName.endsWith(ASSIGNMENT_VALUE_SUFFIX)) {
                 // Set up the execution context for Simple and register our two listeners
-                slContext = new SLContext(new BufferedReader(new StringReader(testCase.testInput)), printer);
+                slContext = SLContextFactory.create(new BufferedReader(new StringReader(testCase.testInput)), printer);
 
                 final Source source = Source.fromText(readAllLines(testCase.path), testCase.sourceName);
                 Parser.parseSL(slContext, source);
-                List<SLFunction> functionList = slContext.getFunctionRegistry().getFunctions();
 
-                // Since only functions can be global in SL, this guarantees that we instrument
-                // everything of interest. Parsing must occur before accepting the visitors since
-                // the visitor which creates our instrumentation points expects a complete AST.
-
-                for (SLFunction function : functionList) {
-                    RootCallTarget rootCallTarget = function.getCallTarget();
-                    if (rootCallTarget != null) {
-                        rootCallTarget.getRootNode().accept(new SLInstrumenter());
-                    }
-                }
-
-                // We iterate over all tags the SLInsturmenter tagged as assignments and attach our
-                // test instrument to those.
-                for (Probe probe : slContext.findProbesTaggedAs(StandardSyntaxTag.ASSIGNMENT)) {
-                    if (probe.isTaggedAs(StandardSyntaxTag.ASSIGNMENT)) {
-                        probe.addInstrument(new SLPrintAssigmentValueInstrument(printer));
-                    }
+                // Attach an instrument to every probe tagged as an assignment
+                for (Probe probe : Probe.findProbesTaggedAs(StandardSyntaxTag.ASSIGNMENT)) {
+                    SLPrintAssigmentValueReciever slPrintAssigmentValueReceiver = new SLPrintAssigmentValueReciever(printer);
+                    probe.attach(Instrument.create(slPrintAssigmentValueReceiver, "SL print assignment value"));
                 }
 
                 SLFunction main = slContext.getFunctionRegistry().lookup("main");
@@ -237,6 +233,7 @@
         } catch (Throwable ex) {
             notifier.fireTestFailure(new Failure(testCase.name, ex));
         } finally {
+            Probe.unregisterASTProber(prober);
             notifier.fireTestFinished(testCase.name);
         }
 
@@ -272,4 +269,25 @@
             return "Filter contains " + pattern;
         }
     }
+
+    /**
+     * This sample instrument receiver provides prints the value of an assignment (after the
+     * assignment is complete) to the {@link PrintStream} specified in the constructor. This
+     * instrument can only be attached to a wrapped {@link SLWriteLocalVariableNode}, but provides
+     * no guards to protect it from being attached elsewhere.
+     */
+    public final class SLPrintAssigmentValueReciever extends DefaultEventReceiver {
+
+        private PrintStream output;
+
+        public SLPrintAssigmentValueReciever(PrintStream output) {
+            this.output = output;
+        }
+
+        @Override
+        public void returnValue(Node node, VirtualFrame frame, Object result) {
+            output.println(result);
+        }
+    }
+
 }