diff graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java @ 21356:e34bc00733d1

Truffle/Instrumentation: an Advanced Instrument can now be created that requires the evaluation result be of a specified type, reporting a failure if not
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Tue, 12 May 2015 17:29:49 -0700
parents 442b57a7f208
children 19801a65cf57
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java	Tue May 12 16:06:00 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java	Tue May 12 17:29:49 2015 -0700
@@ -133,11 +133,13 @@
      *
      * @param resultListener optional client callback for results/failure notification
      * @param rootFactory provider of AST fragments on behalf of the client
+     * @param requiredResultType optional requirement, any non-assignable result is reported to the
+     *            the listener, if any, as a failure
      * @param instrumentInfo optional description of the instrument's role, intended for debugging.
      * @return a new instrument, ready for attachment at a probe
      */
-    public static Instrument create(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, String instrumentInfo) {
-        return new AdvancedInstrument(resultListener, rootFactory, instrumentInfo);
+    public static Instrument create(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, Class<?> requiredResultType, String instrumentInfo) {
+        return new AdvancedInstrument(resultListener, rootFactory, requiredResultType, instrumentInfo);
     }
 
     // TODO (mlvdv) experimental
@@ -383,16 +385,14 @@
     private static final class AdvancedInstrument extends Instrument {
 
         private final AdvancedInstrumentResultListener resultListener;
-        /**
-         * Client-provided supplier of new node instances to attach.
-         */
         private final AdvancedInstrumentRootFactory rootFactory;
+        private final Class<?> requiredResultType;
 
-        private AdvancedInstrument(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, String instrumentInfo) {
+        private AdvancedInstrument(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, Class<?> requiredResultType, String instrumentInfo) {
             super(instrumentInfo);
             this.resultListener = resultListener;
             this.rootFactory = rootFactory;
-
+            this.requiredResultType = requiredResultType;
         }
 
         @Override
@@ -448,6 +448,7 @@
                     try {
                         final Object result = instrumentRoot.executeRoot(node, vFrame);
                         if (resultListener != null) {
+                            checkResultType(result);
                             resultListener.notifyResult(node, vFrame, result);
                         }
                     } catch (RuntimeException ex) {
@@ -461,6 +462,15 @@
                 }
             }
 
+            private void checkResultType(Object result) {
+                if (requiredResultType == null) {
+                    return;
+                }
+                if (result == null || !(requiredResultType.isAssignableFrom(result.getClass()))) {
+                    throw new RuntimeException("Instrument result " + result.toString() + " not assignable to " + requiredResultType.getSimpleName());
+                }
+            }
+
             public void returnVoid(Node node, VirtualFrame vFrame) {
                 if (nextInstrumentNode != null) {
                     nextInstrumentNode.returnVoid(node, vFrame);