# HG changeset patch # User Michael Van De Vanter # Date 1444337322 14400 # Node ID 260e3cdf11ec01e7a9f33f581244142959209bef # Parent 371045b1312d412bafa29882e6c3f7bfe6c0f8f1 Truffle/Instrumentation: replace (non-functional) AdvancedInstrument kind with new EvalInstrument - new API much simpler: only new method Instrumenter.attach() plus new kind of listener - removed the "expected result type check", which is now left to clients - the code to be evaluated now represented as a Source diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestingLanguage.java --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestingLanguage.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestingLanguage.java Thu Oct 08 16:48:42 2015 -0400 @@ -27,8 +27,6 @@ import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; import com.oracle.truffle.api.instrument.Visualizer; import com.oracle.truffle.api.instrument.WrapperNode; import com.oracle.truffle.api.nodes.Node; @@ -82,11 +80,6 @@ } @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - return null; - } - - @Override protected Object createContext(Env env) { return null; } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/LanguageRegistrationTest.java --- a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/LanguageRegistrationTest.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/LanguageRegistrationTest.java Thu Oct 08 16:48:42 2015 -0400 @@ -28,8 +28,6 @@ import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.dsl.test.ExpectError; import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; import com.oracle.truffle.api.instrument.Visualizer; import com.oracle.truffle.api.instrument.WrapperNode; import com.oracle.truffle.api.nodes.Node; @@ -100,11 +98,6 @@ } @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - return null; - } - - @Override protected Object createContext(Env env) { throw new UnsupportedOperationException(); } @@ -159,11 +152,6 @@ } @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - return null; - } - - @Override protected Object createContext(Env env) { throw new UnsupportedOperationException(); } @@ -214,11 +202,6 @@ } @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - return null; - } - - @Override protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { throw new IOException(); } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TestingLanguage.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TestingLanguage.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TestingLanguage.java Thu Oct 08 16:48:42 2015 -0400 @@ -27,8 +27,6 @@ import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; import com.oracle.truffle.api.instrument.Visualizer; import com.oracle.truffle.api.instrument.WrapperNode; import com.oracle.truffle.api.nodes.Node; @@ -81,11 +79,6 @@ } @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - return null; - } - - @Override protected Object createContext(Env env) { return null; } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/AdvancedInstrumentTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/AdvancedInstrumentTest.java Thu Oct 01 20:32:49 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.test.instrument; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import java.io.IOException; -import java.lang.reflect.Field; - -import org.junit.Test; - -import com.oracle.truffle.api.instrument.AdvancedInstrumentRoot; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; -import com.oracle.truffle.api.instrument.Instrumenter; -import com.oracle.truffle.api.instrument.Probe; -import com.oracle.truffle.api.instrument.SyntaxTag; -import com.oracle.truffle.api.instrument.impl.DefaultProbeListener; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.test.instrument.InstrumentationTestNodes.TestAdvancedInstrumentCounterRoot; -import com.oracle.truffle.api.test.instrument.InstrumentationTestingLanguage.InstrumentTestTag; -import com.oracle.truffle.api.vm.PolyglotEngine; - -/** - * Tests the kind of instrumentation where a client can provide an AST fragment to be - * spliced directly into the AST. - */ -public class AdvancedInstrumentTest { - - @Test - public void testAdvancedInstrumentListener() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException { - - final PolyglotEngine vm = PolyglotEngine.buildNew().build(); - final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); - field.setAccessible(true); - final Instrumenter instrumenter = (Instrumenter) field.get(vm); - - instrumenter.registerASTProber(new InstrumentationTestingLanguage.TestASTProber()); - final Source source = Source.fromText("testAdvancedInstrumentListener text", "testAdvancedInstrumentListener").withMimeType("text/x-instTest"); - - final Probe[] addNodeProbe = new Probe[1]; - instrumenter.addProbeListener(new DefaultProbeListener() { - - @Override - public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { - if (tag == InstrumentTestTag.ADD_TAG) { - assertNull("only one add node", addNodeProbe[0]); - addNodeProbe[0] = probe; - } - } - }); - assertEquals(vm.eval(source).get(), 13); - assertNotNull("Add node should be probed", addNodeProbe[0]); - - // Attach a factory that never actually attaches a node. - final AdvancedInstrumentRootFactory rootFactory1 = new AdvancedInstrumentRootFactory() { - - public AdvancedInstrumentRoot createInstrumentRoot(Probe p, Node n) { - return null; - } - }; - instrumenter.attach(addNodeProbe[0], null, rootFactory1, null, "test AdvancedInstrument"); - - assertEquals(vm.eval(source).get(), 13); - - // Attach a factory that splices an execution counter into the AST. - final TestAdvancedInstrumentCounterRoot counter = new TestAdvancedInstrumentCounterRoot(); - final AdvancedInstrumentRootFactory rootFactory2 = new AdvancedInstrumentRootFactory() { - - public AdvancedInstrumentRoot createInstrumentRoot(Probe p, Node n) { - return counter; - } - }; - instrumenter.attach(addNodeProbe[0], null, rootFactory2, null, "test AdvancedInstrument"); - - assertEquals(0, counter.getCount()); - assertEquals(vm.eval(source).get(), 13); - assertEquals(1, counter.getCount()); - } -} diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/EvalInstrumentTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/EvalInstrumentTest.java Thu Oct 08 16:48:42 2015 -0400 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.test.instrument; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.lang.reflect.Field; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.instrument.EvalInstrumentListener; +import com.oracle.truffle.api.instrument.Instrument; +import com.oracle.truffle.api.instrument.Instrumenter; +import com.oracle.truffle.api.instrument.Probe; +import com.oracle.truffle.api.instrument.SyntaxTag; +import com.oracle.truffle.api.instrument.impl.DefaultProbeListener; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.test.instrument.InstrumentationTestingLanguage.InstrumentTestTag; +import com.oracle.truffle.api.vm.PolyglotEngine; + +/** + * Tests the kind of instrumentation where a client can provide guest language code to be + * spliced directly into the AST. + */ +public class EvalInstrumentTest { + + PolyglotEngine vm; + Instrumenter instrumenter; + + @Before + public void before() { + // TODO (mlvdv) eventually abstract this + try { + vm = PolyglotEngine.buildNew().build(); + final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); + field.setAccessible(true); + instrumenter = (Instrumenter) field.get(vm); + final java.lang.reflect.Field testVMField = Instrumenter.class.getDeclaredField("testVM"); + testVMField.setAccessible(true); + testVMField.set(instrumenter, vm); + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { + fail("Reflective access to Instrumenter for testing"); + } + } + + @After + public void after() { + vm.dispose(); + vm = null; + instrumenter = null; + } + + @Test + public void testEvalInstrumentListener() throws IOException { + + instrumenter.registerASTProber(new InstrumentationTestingLanguage.TestASTProber()); + final Source source13 = InstrumentationTestingLanguage.createAdditionSource13("testEvalInstrumentListener"); + + final Probe[] addNodeProbe = new Probe[1]; + instrumenter.addProbeListener(new DefaultProbeListener() { + + @Override + public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { + if (tag == InstrumentTestTag.ADD_TAG) { + addNodeProbe[0] = probe; + } + } + }); + assertEquals(vm.eval(source13).get(), 13); + assertNotNull("Add node should be probed", addNodeProbe[0]); + + final Source source42 = InstrumentationTestingLanguage.createConstantSource42("testEvalInstrumentListener"); + final int[] evalResult = {0}; + final int[] evalCount = {0}; + final Instrument instrument = instrumenter.attach(addNodeProbe[0], InstrumentationTestingLanguage.class, source42, new EvalInstrumentListener() { + + public void onExecution(Node node, VirtualFrame vFrame, Object result) { + evalCount[0] = evalCount[0] + 1; + if (result instanceof Integer) { + evalResult[0] = (Integer) result; + } + } + + public void onFailure(Node node, VirtualFrame vFrame, Exception ex) { + fail("Eval test evaluates without exception"); + + } + }, "test EvalInstrument"); + + assertEquals(vm.eval(source13).get(), 13); + assertEquals(evalCount[0], 1); + assertEquals(evalResult[0], 42); + + // Second execution; same result + assertEquals(vm.eval(source13).get(), 13); + assertEquals(evalCount[0], 2); + assertEquals(evalResult[0], 42); + + // Add new eval instrument with no listener, no effect on third execution + instrumenter.attach(addNodeProbe[0], InstrumentationTestingLanguage.class, source42, null, ""); + assertEquals(vm.eval(source13).get(), 13); + assertEquals(evalCount[0], 3); + assertEquals(evalResult[0], 42); + + // Remove original instrument; no further effect from fourth execution + instrument.dispose(); + evalResult[0] = 0; + assertEquals(vm.eval(source13).get(), 13); + assertEquals(evalCount[0], 3); + assertEquals(evalResult[0], 0); + } +} diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java Thu Oct 08 16:48:42 2015 -0400 @@ -69,7 +69,7 @@ field.setAccessible(true); final Instrumenter instrumenter = (Instrumenter) field.get(vm); instrumenter.registerASTProber(new TestASTProber(instrumenter)); - final Source source = Source.fromText("testProbing text", "testProbing").withMimeType("text/x-instTest"); + final Source source = InstrumentationTestingLanguage.createAdditionSource13("testProbing"); final Probe[] probes = new Probe[3]; instrumenter.addProbeListener(new DefaultProbeListener() { @@ -110,7 +110,7 @@ final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); field.setAccessible(true); final Instrumenter instrumenter = (Instrumenter) field.get(vm); - final Source source = Source.fromText("testTagging text", "testTagging").withMimeType("text/x-instTest"); + final Source source = InstrumentationTestingLanguage.createAdditionSource13("testTagging"); // Applies appropriate tags final TestASTProber astProber = new TestASTProber(instrumenter); diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestNodes.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestNodes.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestNodes.java Thu Oct 08 16:48:42 2015 -0400 @@ -24,7 +24,6 @@ import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRoot; import com.oracle.truffle.api.instrument.EventHandlerNode; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.KillException; @@ -187,23 +186,4 @@ } } - static class TestAdvancedInstrumentCounterRoot extends AdvancedInstrumentRoot { - - private long count; - - @Override - public Object executeRoot(Node node, VirtualFrame vFrame) { - count++; - return null; - } - - public long getCount() { - return count; - } - - public String instrumentationInfo() { - return null; - } - } - } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestingLanguage.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestingLanguage.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTestingLanguage.java Thu Oct 08 16:48:42 2015 -0400 @@ -30,8 +30,6 @@ import com.oracle.truffle.api.TruffleRuntime; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.instrument.ASTProber; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.SyntaxTag; import com.oracle.truffle.api.instrument.Visualizer; @@ -51,6 +49,19 @@ public static final InstrumentationTestingLanguage INSTANCE = new InstrumentationTestingLanguage(); + private static final String ADD_SOURCE_TEXT = "Fake source text for testing: parses to 6 + 7"; + private static final String CONSTANT_SOURCE_TEXT = "Fake source text for testing: parses to 42"; + + /** Use a unique test name to avoid unexpected CallTarget sharing. */ + static Source createAdditionSource13(String testName) { + return Source.fromText(ADD_SOURCE_TEXT, testName).withMimeType("text/x-instTest"); + } + + /** Use a unique test name to avoid unexpected CallTarget sharing. */ + static Source createConstantSource42(String testName) { + return Source.fromText(CONSTANT_SOURCE_TEXT, testName).withMimeType("text/x-instTest"); + } + static enum InstrumentTestTag implements SyntaxTag { ADD_TAG("addition", "test language addition node"), @@ -78,14 +89,24 @@ } @Override - protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { - final TestValueNode leftValueNode = new TestValueNode(6); - final TestValueNode rightValueNode = new TestValueNode(7); - final TestAdditionNode addNode = new TestAdditionNode(leftValueNode, rightValueNode); - final InstrumentationTestRootNode rootNode = new InstrumentationTestRootNode(addNode); - final TruffleRuntime runtime = Truffle.getRuntime(); - final CallTarget callTarget = runtime.createCallTarget(rootNode); - return callTarget; + protected CallTarget parse(Source source, Node context, String... argumentNames) throws IOException { + if (source.getCode().equals(ADD_SOURCE_TEXT)) { + final TestValueNode leftValueNode = new TestValueNode(6); + final TestValueNode rightValueNode = new TestValueNode(7); + final TestAdditionNode addNode = new TestAdditionNode(leftValueNode, rightValueNode); + final InstrumentationTestRootNode rootNode = new InstrumentationTestRootNode(addNode); + final TruffleRuntime runtime = Truffle.getRuntime(); + final CallTarget callTarget = runtime.createCallTarget(rootNode); + return callTarget; + } + if (source.getCode().equals(CONSTANT_SOURCE_TEXT)) { + final TestValueNode constantNode = new TestValueNode(42); + final InstrumentationTestRootNode rootNode = new InstrumentationTestRootNode(constantNode); + final TruffleRuntime runtime = Truffle.getRuntime(); + final CallTarget callTarget = runtime.createCallTarget(rootNode); + return callTarget; + } + return null; } @Override @@ -127,11 +148,6 @@ } @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - return null; - } - - @Override protected Object createContext(Env env) { return null; } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java Thu Oct 08 16:48:42 2015 -0400 @@ -45,8 +45,6 @@ import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; import com.oracle.truffle.api.instrument.Visualizer; import com.oracle.truffle.api.instrument.WrapperNode; import com.oracle.truffle.api.nodes.Node; @@ -210,11 +208,6 @@ return null; } - @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - return null; - } - private Object importExport(Source code) { assertNotEquals("Should run asynchronously", Thread.currentThread(), mainThread); final Node node = createFindContextNode(); diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/InitializationTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/InitializationTest.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/InitializationTest.java Thu Oct 08 16:48:42 2015 -0400 @@ -22,10 +22,10 @@ */ package com.oracle.truffle.api.test.vm; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import java.io.IOException; import java.lang.reflect.Field; @@ -42,8 +42,6 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.instrument.ASTProber; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; import com.oracle.truffle.api.instrument.EventHandlerNode; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.Probe; @@ -101,22 +99,17 @@ Source source = Source.fromText("accessProbeForAbstractLanguage text", "accessProbeForAbstractLanguage").withMimeType("application/x-abstrlang"); - vm.eval(source); + assertEquals(vm.eval(source).get(), 1); assertNotNull("Debugger found", arr[0]); - try { - Debugger d = arr[0]; - Breakpoint b = d.setLineBreakpoint(0, source.createLineLocation(1), true); - assertTrue(b.isEnabled()); - b.setCondition("true"); + Debugger d = arr[0]; + Breakpoint b = d.setLineBreakpoint(0, source.createLineLocation(1), true); + assertTrue(b.isEnabled()); + b.setCondition("true"); - vm.eval(source); - } catch (InstrumentOKException ex) { - // OK - return; - } - fail("We should properly call up to TestLanguage.createAdvancedInstrumentRootFactory"); + assertEquals(vm.eval(source).get(), 1); + vm.dispose(); } private static final class MMRootNode extends RootNode { @@ -220,11 +213,6 @@ } @Override - public AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) { - throw new InstrumentOKException(); - } - - @Override public Visualizer getVisualizer() { throw new UnsupportedOperationException(); } @@ -239,8 +227,4 @@ return node instanceof ANode ? new ANodeWrapper((ANode) node) : null; } } - - private static final class InstrumentOKException extends RuntimeException { - static final long serialVersionUID = 1L; - } } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java Thu Oct 08 16:48:42 2015 -0400 @@ -46,9 +46,6 @@ import com.oracle.truffle.api.impl.Accessor; import com.oracle.truffle.api.impl.FindContextNode; import com.oracle.truffle.api.instrument.ASTProber; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRoot; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.SyntaxTag; import com.oracle.truffle.api.instrument.Visualizer; @@ -269,21 +266,6 @@ protected abstract Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException; /** - * Creates a language-specific factory to produce instances of {@link AdvancedInstrumentRoot} - * that, when executed, computes the result of a textual expression in the language; used to - * create an - * {@linkplain Instrumenter#attach(com.oracle.truffle.api.instrument.Probe, AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String)} - * . - * - * @param expr a guest language expression - * @param resultListener optional listener for the result of each evaluation. - * @return a new factory - * @throws IOException if the factory cannot be created, for example if the expression is badly - * formed. - */ - protected abstract AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException; - - /** * Allows a language implementor to create a node that can effectively lookup up the context * associated with current execution. The context is created by * {@link #createContext(com.oracle.truffle.api.TruffleLanguage.Env)} method. @@ -449,6 +431,11 @@ private static final Map COMPILED = Collections.synchronizedMap(new WeakHashMap()); @Override + protected CallTarget parse(TruffleLanguage truffleLanguage, Source code, Node context, String... argumentNames) throws IOException { + return truffleLanguage.parse(code, context, argumentNames); + } + + @Override protected Object eval(TruffleLanguage language, Source source) throws IOException { CallTarget target = COMPILED.get(source); if (target == null) { @@ -477,15 +464,6 @@ return target.call(); } - @SuppressWarnings("deprecation") - @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(Object vm, Class languageClass, String expr, - AdvancedInstrumentResultListener resultListener) throws IOException { - - final TruffleLanguage language = findLanguageImpl(vm, languageClass); - return language.createAdvancedInstrumentRootFactory(expr, resultListener); - } - @Override protected Object findExportedSymbol(TruffleLanguage.Env env, String globalName, boolean onlyExplicit) { return env.langCtx.findExportedSymbol(globalName, onlyExplicit); diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Breakpoint.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Breakpoint.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Breakpoint.java Thu Oct 08 16:48:42 2015 -0400 @@ -142,10 +142,10 @@ public abstract void setCondition(String expr) throws IOException; /** - * Gets the string, expressed in the Guest Language, that defines the current condition on this - * breakpoint; {@code null} if this breakpoint is currently unconditional. + * Gets the text that defines the current condition on this breakpoint; {@code null} if this + * breakpoint is currently unconditional. */ - public String getCondition() { + public Source getCondition() { return null; } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java Thu Oct 08 16:48:42 2015 -0400 @@ -34,14 +34,11 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleLanguage; -import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.frame.FrameInstance; import com.oracle.truffle.api.frame.FrameInstanceVisitor; import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.impl.Accessor; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRoot; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.KillException; import com.oracle.truffle.api.instrument.Probe; @@ -273,26 +270,6 @@ debugContext.setStrategy(new StepOver(stepCount)); } - // TODO (mlvdv) used by the breakpoint factories; to be deprecated/replaced. - /** - * Creates a language-specific factory to produce instances of {@link AdvancedInstrumentRoot} - * that, when executed, computes the result of a textual expression in the language; used to - * create an - * {@linkplain Instrumenter#attach(Probe, AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String) - * Advanced Instrument}. - * - * @param expr a guest language expression - * @param resultListener optional listener for the result of each evaluation. - * @return a new factory - * @throws IOException if the factory cannot be created, for example if the expression is badly - * formed. - */ - @SuppressWarnings("rawtypes") - AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(Probe probe, String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - Class languageClass = ACCESSOR.findLanguage(probe); - return ACCESSOR.createAdvancedInstrumentRootFactory(vm, languageClass, expr, resultListener); - } - Instrumenter getInstrumenter() { return instrumenter; } @@ -860,7 +837,7 @@ } @SuppressWarnings("rawtypes") - private static final class AccessorDebug extends Accessor { + static final class AccessorDebug extends Accessor { @Override protected Closeable executionStart(Object vm, final Debugger debugger, Source s) { @@ -883,13 +860,6 @@ return super.findLanguage(probe); } - @SuppressWarnings("deprecation") - @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(Object vm, Class languageClass, String expr, - AdvancedInstrumentResultListener resultListener) throws IOException { - return super.createAdvancedInstrumentRootFactory(vm, languageClass, expr, resultListener); - } - @Override protected void dispatchEvent(Object vm, Object event) { super.dispatchEvent(vm, event); @@ -902,5 +872,5 @@ } // registers into Accessor.DEBUG - private static final AccessorDebug ACCESSOR = new AccessorDebug(); + static final AccessorDebug ACCESSOR = new AccessorDebug(); } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/LineBreakpointFactory.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/LineBreakpointFactory.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/LineBreakpointFactory.java Thu Oct 08 16:48:42 2015 -0400 @@ -44,13 +44,14 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.debug.Debugger.BreakpointCallback; import com.oracle.truffle.api.debug.Debugger.WarningLog; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.ProbeInstrument; +import com.oracle.truffle.api.instrument.EvalInstrumentListener; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.Probe; +import com.oracle.truffle.api.instrument.ProbeInstrument; import com.oracle.truffle.api.instrument.StandardSyntaxTag; import com.oracle.truffle.api.instrument.SyntaxTag; import com.oracle.truffle.api.instrument.impl.DefaultProbeListener; @@ -58,6 +59,7 @@ import com.oracle.truffle.api.nodes.InvalidAssumptionException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.LineLocation; +import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.api.utilities.CyclicAssumption; @@ -153,14 +155,7 @@ // A Probe with line location tagged STATEMENT we haven't seen before. final LineBreakpointImpl breakpoint = lineToBreakpoint.get(lineLocation); if (breakpoint != null) { - try { - breakpoint.attach(probe); - } catch (IOException e) { - warningLog.addWarning(BREAKPOINT_NAME + " failure attaching to newly tagged Probe: " + e.getMessage()); - if (TRACE) { - OUT.println(BREAKPOINT_NAME + " failure: " + e.getMessage()); - } - } + breakpoint.attach(probe); } } } @@ -273,7 +268,7 @@ * Concrete representation of a line breakpoint, implemented by attaching an instrument to a * probe at the designated source location. */ - private final class LineBreakpointImpl extends LineBreakpoint implements AdvancedInstrumentResultListener { + private final class LineBreakpointImpl extends LineBreakpoint implements EvalInstrumentListener { private static final String SHOULD_NOT_HAPPEN = "LineBreakpointImpl: should not happen"; @@ -286,7 +281,7 @@ @CompilationFinal private boolean isEnabled; private Assumption enabledUnchangedAssumption; - private String conditionExpr; + private Source conditionSource; /** * The instrument(s) that this breakpoint currently has attached to a {@link Probe}: @@ -344,7 +339,7 @@ @Override public void setCondition(String expr) throws IOException { - if (this.conditionExpr != null || expr != null) { + if (this.conditionSource != null || expr != null) { // De-instrument the Probes instrumented by this breakpoint final ArrayList probes = new ArrayList<>(); for (ProbeInstrument instrument : instruments) { @@ -352,7 +347,7 @@ instrument.dispose(); } instruments.clear(); - this.conditionExpr = expr; + this.conditionSource = Source.fromText(expr, "breakpoint condition from text: " + expr); // Re-instrument the probes previously instrumented for (Probe probe : probes) { attach(probe); @@ -361,8 +356,8 @@ } @Override - public String getCondition() { - return conditionExpr; + public Source getCondition() { + return conditionSource; } @TruffleBoundary @@ -377,16 +372,18 @@ } } - private void attach(Probe newProbe) throws IOException { + @SuppressWarnings("rawtypes") + private void attach(Probe newProbe) { if (getState() == DISPOSED) { throw new IllegalStateException("Attempt to attach a disposed " + BREAKPOINT_NAME); } ProbeInstrument newInstrument = null; final Instrumenter instrumenter = debugger.getInstrumenter(); - if (conditionExpr == null) { + if (conditionSource == null) { newInstrument = instrumenter.attach(newProbe, new UnconditionalLineBreakInstrumentListener(), BREAKPOINT_NAME); } else { - newInstrument = instrumenter.attach(newProbe, this, debugger.createAdvancedInstrumentRootFactory(newProbe, conditionExpr, this), Boolean.class, BREAKPOINT_NAME); + final Class languageClass = Debugger.ACCESSOR.findLanguage(newProbe); + newInstrument = instrumenter.attach(newProbe, languageClass, conditionSource, this, BREAKPOINT_NAME); } instruments.add(newInstrument); changeState(isEnabled ? ENABLED : DISABLED); @@ -447,16 +444,20 @@ } public void onExecution(Node node, VirtualFrame vFrame, Object result) { - final boolean condition = (Boolean) result; - if (TRACE) { - trace("breakpoint condition = %b %s", condition, getShortDescription()); - } - if (condition) { - nodeEnter(node, vFrame); + if (result instanceof Boolean) { + final boolean condition = (Boolean) result; + if (TRACE) { + trace("breakpoint condition = %b %s", condition, getShortDescription()); + } + if (condition) { + nodeEnter(node, vFrame); + } + } else { + onFailure(node, vFrame, new RuntimeException("breakpint failure = non-boolean condition " + result.toString())); } } - public void onFailure(Node node, VirtualFrame vFrame, RuntimeException ex) { + public void onFailure(Node node, VirtualFrame vFrame, Exception ex) { addExceptionWarning(ex); if (TRACE) { trace("breakpoint failure = %s %s", ex, getShortDescription()); @@ -466,7 +467,7 @@ } @TruffleBoundary - private void addExceptionWarning(RuntimeException ex) { + private void addExceptionWarning(Exception ex) { warningLog.addWarning(String.format("Exception in %s: %s", getShortDescription(), ex.getMessage())); } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/TagBreakpointFactory.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/TagBreakpointFactory.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/TagBreakpointFactory.java Thu Oct 08 16:48:42 2015 -0400 @@ -42,10 +42,11 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.debug.Debugger.BreakpointCallback; import com.oracle.truffle.api.debug.Debugger.WarningLog; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; +import com.oracle.truffle.api.instrument.EvalInstrumentListener; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.Probe; import com.oracle.truffle.api.instrument.ProbeInstrument; @@ -54,6 +55,7 @@ import com.oracle.truffle.api.instrument.impl.DefaultStandardInstrumentListener; import com.oracle.truffle.api.nodes.InvalidAssumptionException; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.utilities.CyclicAssumption; // TODO (mlvdv) some common functionality could be factored out of this and LineBreakpointSupport @@ -132,14 +134,7 @@ public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { final TagBreakpointImpl breakpoint = tagToBreakpoint.get(tag); if (breakpoint != null) { - try { - breakpoint.attach(probe); - } catch (IOException e) { - warningLog.addWarning(BREAKPOINT_NAME + " failure attaching to newly tagged Probe: " + e.getMessage()); - if (TRACE) { - OUT.println(BREAKPOINT_NAME + " failure: " + e.getMessage()); - } - } + breakpoint.attach(probe); } } }); @@ -242,7 +237,7 @@ * Concrete representation of a line breakpoint, implemented by attaching an instrument to a * probe at the designated source location. */ - private final class TagBreakpointImpl extends TagBreakpoint implements AdvancedInstrumentResultListener { + private final class TagBreakpointImpl extends TagBreakpoint implements EvalInstrumentListener { private static final String SHOULD_NOT_HAPPEN = "TagBreakpointImpl: should not happen"; @@ -255,7 +250,7 @@ @CompilationFinal private boolean isEnabled; private Assumption enabledUnchangedAssumption; - private String conditionExpr; + private Source conditionSource; /** * The instrument(s) that this breakpoint currently has attached to a {@link Probe}: @@ -305,7 +300,7 @@ @Override public void setCondition(String expr) throws IOException { - if (this.conditionExpr != null || expr != null) { + if (this.conditionSource != null || expr != null) { // De-instrument the Probes instrumented by this breakpoint final ArrayList probes = new ArrayList<>(); for (ProbeInstrument instrument : instruments) { @@ -313,7 +308,7 @@ instrument.dispose(); } instruments.clear(); - this.conditionExpr = expr; + this.conditionSource = Source.fromText(expr, "breakpoint condition for text: " + expr); // Re-instrument the probes previously instrumented for (Probe probe : probes) { attach(probe); @@ -322,8 +317,8 @@ } @Override - public String getCondition() { - return conditionExpr; + public Source getCondition() { + return conditionSource; } @TruffleBoundary @@ -338,16 +333,18 @@ } } - private void attach(Probe newProbe) throws IOException { + @SuppressWarnings("rawtypes") + private void attach(Probe newProbe) { if (getState() == DISPOSED) { throw new IllegalStateException("Attempt to attach a disposed " + BREAKPOINT_NAME); } ProbeInstrument newInstrument = null; final Instrumenter instrumenter = debugger.getInstrumenter(); - if (conditionExpr == null) { + if (conditionSource == null) { newInstrument = instrumenter.attach(newProbe, new UnconditionalTagBreakInstrumentListener(), BREAKPOINT_NAME); } else { - instrumenter.attach(newProbe, this, debugger.createAdvancedInstrumentRootFactory(newProbe, conditionExpr, this), Boolean.class, BREAKPOINT_NAME); + final Class languageClass = Debugger.ACCESSOR.findLanguage(newProbe); + instrumenter.attach(newProbe, languageClass, conditionSource, this, BREAKPOINT_NAME); } instruments.add(newInstrument); changeState(isEnabled ? ENABLED : DISABLED); @@ -409,16 +406,20 @@ } public void onExecution(Node node, VirtualFrame vFrame, Object result) { - final boolean condition = (Boolean) result; - if (TRACE) { - trace("breakpoint condition = %b %s", condition, getShortDescription()); - } - if (condition) { - nodeEnter(node, vFrame); + if (result instanceof Boolean) { + final boolean condition = (Boolean) result; + if (TRACE) { + trace("breakpoint condition = %b %s", condition, getShortDescription()); + } + if (condition) { + nodeEnter(node, vFrame); + } + } else { + onFailure(node, vFrame, new RuntimeException("breakpint failure = non-boolean condition " + result.toString())); } } - public void onFailure(Node node, VirtualFrame vFrame, RuntimeException ex) { + public void onFailure(Node node, VirtualFrame vFrame, Exception ex) { addExceptionWarning(ex); if (TRACE) { trace("breakpoint failure = %s %s", ex, getShortDescription()); @@ -428,7 +429,7 @@ } @TruffleBoundary - private void addExceptionWarning(RuntimeException ex) { + private void addExceptionWarning(Exception ex) { warningLog.addWarning(String.format("Exception in %s: %s", getShortDescription(), ex.getMessage())); } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java Thu Oct 08 16:48:42 2015 -0400 @@ -41,8 +41,6 @@ import com.oracle.truffle.api.frame.FrameInstance; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.instrument.ASTProber; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.Probe; import com.oracle.truffle.api.instrument.Visualizer; @@ -108,11 +106,6 @@ protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { return null; } - - @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - return null; - } }; lng.hashCode(); new Node(null) { @@ -209,13 +202,6 @@ return API.createWrapperNode(node, language); } - @Deprecated - @SuppressWarnings("rawtypes") - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(Object vm, Class languageClass, String expr, AdvancedInstrumentResultListener resultListener) - throws IOException { - return API.createAdvancedInstrumentRootFactory(vm, languageClass, expr, resultListener); - } - @SuppressWarnings("rawtypes") protected Class findLanguage(RootNode n) { return NODES.findLanguage(n); @@ -341,4 +327,15 @@ protected void dispose(TruffleLanguage impl, Env env) { API.dispose(impl, env); } + + @SuppressWarnings("rawtypes") + protected CallTarget parse(Class languageClass, Source code, Node context, String... argumentNames) throws IOException { + final TruffleLanguage truffleLanguage = findLanguageImpl(null, languageClass); + return parse(truffleLanguage, code, context, argumentNames); + } + + protected CallTarget parse(TruffleLanguage truffleLanguage, Source code, Node context, String... argumentNames) throws IOException { + return API.parse(truffleLanguage, code, context, argumentNames); + } + } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentResultListener.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentResultListener.java Thu Oct 01 20:32:49 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.instrument; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; - -/** - * Listener for receiving the result a client-provided {@linkplain AdvancedInstrumentRoot AST - * fragment}, when executed by a - * {@linkplain Instrumenter#attach(Probe, AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String) - * Advanced Instrument}. - *

- * Notification is fully synchronous, so overrides have performance implications. Non-trivial - * methods should be coded with Truffle guidelines and cautions in mind. - * - * @see ProbeInstrument - * @see AdvancedInstrumentRoot - * @see AdvancedInstrumentRootFactory - */ -public interface AdvancedInstrumentResultListener { - - /** - * Notifies listener that a client-provided {@linkplain AdvancedInstrumentRoot AST fragment} has - * been executed by an - * {@linkplain Instrumenter#attach(Probe, AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String) - * Advanced Instrument} with the specified result, possibly {@code null}. - *

- * Note: Truffle will attempt to optimize implementations through partial - * evaluation; annotate with {@link TruffleBoundary} if this should not be permitted. - * - * @param node the guest-language AST node to which the host Instrument's {@link Probe} is - * attached - * @param vFrame execution frame at the guest-language AST node - * @param result the result of this AST fragment's execution - */ - void onExecution(Node node, VirtualFrame vFrame, Object result); - - /** - * Notifies listener that execution of client-provided {@linkplain AdvancedInstrumentRoot AST - * fragment} filed during execution by a @linkplain - * Instrument#create(AdvancedInstrumentRootFactory, String) Advanced Instrument}. - *

- * Note: Truffle will attempt to optimize implementations through partial - * evaluation; annotate with {@link TruffleBoundary} if this should not be permitted. - * - * @param node the guest-language AST node to which the host Instrument's {@link Probe} is - * attached - * @param vFrame execution frame at the guest-language AST node - * @param ex the exception - */ - void onFailure(Node node, VirtualFrame vFrame, RuntimeException ex); - -} diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentRoot.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentRoot.java Thu Oct 01 20:32:49 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.instrument; - -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; - -/** - * Root of a client-provided AST fragment that can be executed efficiently, subject to full Truffle - * optimization, by an - * {@linkplain Instrumenter#attach(Probe, AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String) - * Advanced Instrument}. - * - * @see ProbeInstrument - * @see AdvancedInstrumentRootFactory - * @see AdvancedInstrumentResultListener - */ -public abstract class AdvancedInstrumentRoot extends Node implements InstrumentationNode { - - /** - * Executes this AST fragment on behalf of a client {@link ProbeInstrument}, just before the - * guest-language AST node to which the {@link Probe} holding the Instrument is executed. - * - * @param node the guest-language AST node to which the host Instrument's Probe is attached - * @param vFrame execution frame at the guest-language AST node - * @return the result of this AST fragment's execution - */ - public abstract Object executeRoot(Node node, VirtualFrame vFrame); - -} diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentRootFactory.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentRootFactory.java Thu Oct 01 20:32:49 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.instrument; - -import com.oracle.truffle.api.nodes.Node; - -/** - * Creator of {@linkplain AdvancedInstrumentRoot AST fragments} suitable for efficient execution, - * subject to full Truffle optimization, by an - * {@linkplain Instrumenter#attach(Probe, AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String) - * Advanced Instrument}. - * - * @see ProbeInstrument - * @see AdvancedInstrumentRoot - */ -public interface AdvancedInstrumentRootFactory { - - /** - * Provider of {@linkplain AdvancedInstrumentRoot AST fragment} instances to be executed by the - * {@linkplain Instrumenter Instrumentation Framework} at a {@linkplain Probe Probed} site in a - * guest-language AST. - *

- * Notes: - *

    - *
  • Once the factory has produced an AST fragment at a particular {@linkplain Node AST Node}, - * it will not be called again at that Node.
  • - *
  • In some use cases, for example to implement a breakpoint at a specific program location, - * the Probe argument will be the same for every call. Each Node argument will represent the - * same program location associated with the Probe, but in different clones of the AST.
  • - *
  • In other use cases, for example to implement a breakpoint at any Node with a particular - * {@linkplain SyntaxTag tag}, both the Probe and Node argument may differ. Implementations that - * are sensitive to the lexical context in which the AST fragment will be evaluated must take - * care to build a new, possibly different AST fragment for each request.
  • - *
- * - * @param probe the Probe to which the Instrument requesting the AST fragment is attached - * @param node the guest-language AST location that is the context in which the requesting - * Instrument must execute the AST fragment. - * @return a newly created AST fragment suitable for execution, via instrumentation, in the - * execution context of the specified guest-language AST site. - */ - AdvancedInstrumentRoot createInstrumentRoot(Probe probe, Node node); -} diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/EvalInstrumentListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/EvalInstrumentListener.java Thu Oct 08 16:48:42 2015 -0400 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.instrument; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +/** + * Listener for receiving the result a client-provided Guest Language expression + * {@linkplain Instrumenter#attach(Probe, Class, Source, EvalListener, String) attached} to a + * {@link Probe}. + *

+ * Notification is fully synchronous, so method bodies have performance implications. Non-trivial + * methods should be coded with Truffle guidelines and cautions in mind. + * + * @see Instrumenter + */ +public interface EvalInstrumentListener { + + /** + * Notifies listener that a client-provided Guest Language expression + * {@linkplain Instrumenter#attach(Probe, Class, Source, EvalListener, String) attached} to a + * {@link Probe} has just been executed with the specified result, possibly {@code null}. + *

+ * Note: Truffle will attempt to optimize implementations through partial + * evaluation; annotate with {@link TruffleBoundary} if this should not be permitted. + * + * @param node the guest language AST node at which the expression was evaluated + * @param vFrame execution frame at the guest-language AST node + * @param result expression evaluation + */ + void onExecution(Node node, VirtualFrame vFrame, Object result); + + /** + * Notifies listener that a client-provided Guest Language expression + * {@linkplain Instrumenter#attach(Probe, Class, Source, EvalListener, String) attached} to a + * {@link Probe} has just been executed and generated an exception. The exception does not + * affect Guest language evaluation; the only report is to listeners implementing this methods. + *

+ * Note: Truffle will attempt to optimize implementations through partial + * evaluation; annotate with {@link TruffleBoundary} if this should not be permitted. + * + * @param node the guest-language AST node to which the host Instrument's {@link Probe} is + * attached + * @param vFrame execution frame at the guest-language AST node + * @param ex the exception + */ + void onFailure(Node node, VirtualFrame vFrame, Exception ex); + +} diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Thu Oct 08 16:48:42 2015 -0400 @@ -39,19 +39,39 @@ */ public abstract class Instrument { - protected Instrument() { + /** Optional string for debugging. */ + private final String instrumentInfo; + + private boolean isDisposed = false; + + protected Instrument(String instrumentInfo) { + this.instrumentInfo = instrumentInfo; } /** - * Detaches this from its source of execution events and renders itself unusable. + * Detaches this from its source of execution events and makes itself unusable. * * @throws IllegalStateException if this has already been disposed */ - public abstract void dispose() throws IllegalStateException; + public void dispose() throws IllegalStateException { + if (isDisposed) { + throw new IllegalStateException("Istruments only dispose once"); + } + innerDispose(); + this.isDisposed = true; + } /** - * Has this been detached from its source of execution events. + * Has this been detached from its source of execution events? */ - public abstract boolean isDisposed(); + public boolean isDisposed() { + return isDisposed; + } + + protected final String getInstrumentInfo() { + return instrumentInfo; + } + + protected abstract void innerDispose(); } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumenter.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumenter.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumenter.java Thu Oct 08 16:48:42 2015 -0400 @@ -24,6 +24,7 @@ */ package com.oracle.truffle.api.instrument; +import java.io.IOException; import java.io.PrintStream; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -34,9 +35,11 @@ import java.util.List; import java.util.Set; +import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.impl.Accessor; +import com.oracle.truffle.api.instrument.ProbeInstrument.EvalInstrument; import com.oracle.truffle.api.instrument.TagInstrument.AfterTagInstrument; import com.oracle.truffle.api.instrument.TagInstrument.BeforeTagInstrument; import com.oracle.truffle.api.nodes.Node; @@ -422,13 +425,13 @@ * {@linkplain EventHandlerNode execution events} taking place at the Probe's AST location to * the listener. * - * @param probe source of AST execution events + * @param probe source of AST execution events, non-null * @param listener receiver of execution events * @param instrumentInfo optional documentation about the Instrument * @return a handle for access to the binding */ - @SuppressWarnings("static-method") public ProbeInstrument attach(Probe probe, SimpleInstrumentListener listener, String instrumentInfo) { + assert probe.getInstrumenter() == this; final ProbeInstrument instrument = new ProbeInstrument.SimpleInstrument(listener, instrumentInfo); probe.attach(instrument); return instrument; @@ -441,42 +444,45 @@ * {@linkplain EventHandlerNode execution events} taking place at the Probe's AST location to * the listener. * - * @param probe source of AST execution events + * @param probe source of AST execution events, non-null * @param listener receiver of execution events * @param instrumentInfo optional documentation about the Instrument * @return a handle for access to the binding */ - @SuppressWarnings("static-method") public ProbeInstrument attach(Probe probe, StandardInstrumentListener listener, String instrumentInfo) { + assert probe.getInstrumenter() == this; final ProbeInstrument instrument = new ProbeInstrument.StandardInstrument(listener, instrumentInfo); probe.attach(instrument); return instrument; } /** - * Attaches a {@link AdvancedInstrumentResultListener listener} to a {@link Probe}, - * creating a binding called an {@link ProbeInstrument}. Until the Instrument is - * {@linkplain ProbeInstrument#dispose() disposed}, it routes synchronous notification of - * {@linkplain EventHandlerNode execution events} taking place at the Probe's AST location to - * the listener. + * Attaches a fragment of source text that is to be evaluated just before execution + * enters the location of a {@link Probe}, creating a binding called an + * {@link ProbeInstrument}. The outcome of the evaluation is reported to an optional + * {@link EvalInstrumentListener listener}, but the outcome does not affect the flow of guest + * language execution, even if the evaluation produces an exception. *

- * This Instrument executes efficiently, subject to full Truffle optimization, a client-provided - * AST fragment every time the Probed node is entered. + * The source text is assumed to be expressed in the language identified by its associated + * {@linkplain Source#getMimeType() MIME type}, if specified, otherwise by the language + * associated with the AST location associated with the {@link Probe}. *

- * Any {@link RuntimeException} thrown by execution of the fragment is caught by the framework - * and reported to the listener; there is no other notification. + * The source text is parsed in the lexical context of the AST location associated with the + * {@link Probe}. + *

+ * The source text executes subject to full Truffle optimization. * - * @param probe source of AST execution events + * @param probe source of AST execution events, non-null + * @param languageClass the language in which the source text is to be executed + * @param source the source code to be evaluated, non-null and non-empty * @param listener 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 instrumentInfo optional documentation about the Instrument * @return a handle for access to the binding */ - @SuppressWarnings("static-method") - public ProbeInstrument attach(Probe probe, AdvancedInstrumentResultListener listener, AdvancedInstrumentRootFactory rootFactory, Class requiredResultType, String instrumentInfo) { - final ProbeInstrument instrument = new ProbeInstrument.AdvancedInstrument(listener, rootFactory, requiredResultType, instrumentInfo); + @SuppressWarnings("rawtypes") + public ProbeInstrument attach(Probe probe, Class languageClass, Source source, EvalInstrumentListener listener, String instrumentInfo) { + assert probe.getInstrumenter() == this; + final EvalInstrument instrument = new EvalInstrument(languageClass, source, listener, instrumentInfo); probe.attach(instrument); return instrument; } @@ -630,7 +636,7 @@ } @Override - public WrapperNode createWrapperNode(Object vm, Node node) { + protected WrapperNode createWrapperNode(Object vm, Node node) { return super.createWrapperNode(vm, node); } @@ -646,6 +652,12 @@ return probe.getLanguage(); } + @SuppressWarnings("rawtypes") + @Override + protected CallTarget parse(Class languageClass, Source code, Node context, String... argumentNames) throws IOException { + return super.parse(languageClass, code, context, argumentNames); + } + @Override protected void probeAST(RootNode rootNode) { // Normally null vm argument; can be reflectively set for testing diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Thu Oct 08 16:48:42 2015 -0400 @@ -329,4 +329,8 @@ sb.append("]"); return sb.toString(); } + + Instrumenter getInstrumenter() { + return instrumenter; + } } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeInstrument.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeInstrument.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeInstrument.java Thu Oct 08 16:48:42 2015 -0400 @@ -24,12 +24,18 @@ */ package com.oracle.truffle.api.instrument; +import java.io.IOException; + +import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.impl.DefaultDirectCallNode; +import com.oracle.truffle.api.nodes.DirectCallNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeCost; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; /** @@ -49,15 +55,7 @@ */ public abstract class ProbeInstrument extends Instrument { - /** - * Optional documentation, mainly for debugging. - */ - private final String instrumentInfo; - - /** - * Has this instrument been disposed? stays true once set. - */ - private boolean isDisposed = false; + private static final String[] NO_ARGS = new String[0]; protected Probe probe = null; @@ -117,44 +115,31 @@ * */ private ProbeInstrument(String instrumentInfo) { - this.instrumentInfo = instrumentInfo; + super(instrumentInfo); } /** * Removes this Instrument from the Probe to which it attached and renders this Instrument * inert. - * - * @throws IllegalStateException if this instrument has already been disposed */ @Override - public void dispose() throws IllegalStateException { - if (isDisposed) { - throw new IllegalStateException("Attempt to dispose an already disposed Instrumennt"); - } + protected void innerDispose() { if (probe != null) { // It's attached probe.disposeInstrument(this); probe = null; } - this.isDisposed = true; - } - - @Override - public boolean isDisposed() { - return isDisposed; } /** - * Gets the {@link Probe} to which this Instrument is currently attached: {@code null} if not - * yet attached to a Probe or if this Instrument has been {@linkplain #dispose() disposed}. + * Gets the {@link Probe} to which this {@link Instrument} is currently attached: {@code null} + * if not yet attached to a Probe or if this Instrument has been {@linkplain #dispose() + * disposed}. */ public Probe getProbe() { return probe; } - /** - * For internal implementation only. - */ void setAttachedTo(Probe probe) { this.probe = probe; } @@ -250,6 +235,11 @@ final String info = getInstrumentInfo(); return info != null ? info : simpleListener.getClass().getSimpleName(); } + + @Override + public Probe getProbe() { + return SimpleInstrument.this.probe; + } } } @@ -337,30 +327,36 @@ final String info = getInstrumentInfo(); return info != null ? info : standardListener.getClass().getSimpleName(); } + + @Override + public Probe getProbe() { + return StandardInstrument.this.probe; + } } } /** - * An instrument that allows clients to provide an AST fragment to be executed directly from + * An instrument that allows clients to provide guest language code to be executed directly from * within a Probe's instrumentation chain, and thus directly in the executing Truffle * AST with potential for full optimization. */ - static final class AdvancedInstrument extends ProbeInstrument { + static final class EvalInstrument extends ProbeInstrument { - private final AdvancedInstrumentResultListener resultListener; - private final AdvancedInstrumentRootFactory rootFactory; - private final Class requiredResultType; + @SuppressWarnings("rawtypes") private final Class languageClass; + private final Source source; + private final EvalInstrumentListener evalListener; - AdvancedInstrument(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, Class requiredResultType, String instrumentInfo) { + @SuppressWarnings("rawtypes") + EvalInstrument(Class languageClass, Source source, EvalInstrumentListener evalListener, String instrumentInfo) { super(instrumentInfo); - this.resultListener = resultListener; - this.rootFactory = rootFactory; - this.requiredResultType = requiredResultType; + this.languageClass = languageClass; + this.source = source; + this.evalListener = evalListener; } @Override AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) { - return new AdvancedInstrumentNode(nextNode); + return new EvalInstrumentNode(nextNode); } @Override @@ -372,7 +368,7 @@ return instrumentNode.nextInstrumentNode; } // Match not at the head of the chain; remove it. - found = instrumentNode.removeFromChain(AdvancedInstrument.this); + found = instrumentNode.removeFromChain(EvalInstrument.this); } if (!found) { throw new IllegalStateException("Couldn't find instrument node to remove: " + this); @@ -381,43 +377,42 @@ } /** - * Node that implements a {@link AdvancedInstrument} in a particular AST. + * Node that implements an {@link EvalInstrument} in a particular AST. */ @NodeInfo(cost = NodeCost.NONE) - private final class AdvancedInstrumentNode extends AbstractInstrumentNode { + private final class EvalInstrumentNode extends AbstractInstrumentNode { - @Child private AdvancedInstrumentRoot instrumentRoot; + @Child private DirectCallNode callNode; - private AdvancedInstrumentNode(AbstractInstrumentNode nextNode) { + private EvalInstrumentNode(AbstractInstrumentNode nextNode) { super(nextNode); } @Override public void enter(Node node, VirtualFrame vFrame) { - if (instrumentRoot == null) { + if (callNode == null) { try { - final AdvancedInstrumentRoot newInstrumentRoot = AdvancedInstrument.this.rootFactory.createInstrumentRoot(AdvancedInstrument.this.probe, node); - if (newInstrumentRoot != null) { - instrumentRoot = newInstrumentRoot; + final CallTarget callTarget = Instrumenter.ACCESSOR.parse(languageClass, source, node, NO_ARGS); + if (callTarget != null) { + callNode = new DefaultDirectCallNode(callTarget); // force inlining? adoptChildren(); - AdvancedInstrument.this.probe.invalidateProbeUnchanged(); + EvalInstrument.this.probe.invalidateProbeUnchanged(); } - } catch (RuntimeException ex) { - if (resultListener != null) { - resultListener.onFailure(node, vFrame, ex); + } catch (RuntimeException | IOException ex) { + if (evalListener != null) { + evalListener.onFailure(node, vFrame, ex); } } } - if (instrumentRoot != null) { + if (callNode != null) { try { - final Object result = instrumentRoot.executeRoot(node, vFrame); - if (resultListener != null) { - checkResultType(result); - resultListener.onExecution(node, vFrame, result); + final Object result = callNode.call(vFrame, null); + if (evalListener != null) { + evalListener.onExecution(node, vFrame, result); } } catch (RuntimeException ex) { - if (resultListener != null) { - resultListener.onFailure(node, vFrame, ex); + if (evalListener != null) { + evalListener.onFailure(node, vFrame, ex); } } } @@ -426,28 +421,6 @@ } } - private void checkResultType(Object result) { - if (requiredResultType == null) { - return; - } - if (result == null) { - throw instrumentResultNull(); - } - if (!(requiredResultType.isAssignableFrom(result.getClass()))) { - throw instrumentResultWrongType(result); - } - } - - @TruffleBoundary - private RuntimeException instrumentResultNull() { - return new RuntimeException("Instrument result null: " + requiredResultType.getSimpleName() + " is required"); - } - - @TruffleBoundary - private RuntimeException instrumentResultWrongType(Object result) { - return new RuntimeException("Instrument result " + result.toString() + " not assignable to " + requiredResultType.getSimpleName()); - } - @Override public void returnVoid(Node node, VirtualFrame vFrame) { if (nextInstrumentNode != null) { @@ -472,7 +445,7 @@ @Override public String instrumentationInfo() { final String info = getInstrumentInfo(); - return info != null ? info : rootFactory.getClass().getSimpleName(); + return info != null ? info : getInstrumentInfo(); } } } @@ -612,7 +585,7 @@ } protected String getInstrumentInfo() { - return ProbeInstrument.this.instrumentInfo; + return ProbeInstrument.this.getInstrumentInfo(); } } } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/TagInstrument.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/TagInstrument.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/TagInstrument.java Thu Oct 08 16:48:42 2015 -0400 @@ -41,38 +41,14 @@ */ public abstract class TagInstrument extends Instrument { - /** - * Optional documentation, mainly for debugging. - */ - @SuppressWarnings("unused") private final String instrumentInfo; - protected Instrumenter instrumenter; - /** - * Has this instrument been disposed? stays true once set. - */ - protected boolean isDisposed = false; - private SyntaxTag tag = null; protected TagInstrument(Instrumenter instrumenter, SyntaxTag tag, String instrumentInfo) { + super(instrumentInfo); this.instrumenter = instrumenter; this.tag = tag; - this.instrumentInfo = instrumentInfo; - } - - @Override - public void dispose() throws IllegalStateException { - if (isDisposed) { - throw new IllegalStateException("Attempt to dispose an already disposed Instrumennt"); - } - instrumenter.disposeAfterTagInstrument(); - this.isDisposed = true; - } - - @Override - public boolean isDisposed() { - return isDisposed; } public SyntaxTag getTag() { @@ -93,12 +69,8 @@ } @Override - public void dispose() throws IllegalStateException { - if (isDisposed) { - throw new IllegalStateException("Disposed Instrument can not be disposed again"); - } + protected void innerDispose() { instrumenter.disposeBeforeTagInstrument(); - this.isDisposed = true; } } @@ -116,12 +88,8 @@ } @Override - public void dispose() throws IllegalStateException { - if (isDisposed) { - throw new IllegalStateException("Disposed Instrument can not be disposed again"); - } + protected void innerDispose() { instrumenter.disposeAfterTagInstrument(); - this.isDisposed = true; } } } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java Thu Oct 08 16:48:42 2015 -0400 @@ -56,8 +56,6 @@ import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.UnsupportedSpecializationException; import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; import com.oracle.truffle.api.instrument.Visualizer; import com.oracle.truffle.api.instrument.WrapperNode; import com.oracle.truffle.api.nodes.GraphPrintVisitor; @@ -509,11 +507,6 @@ throw new IllegalStateException("evalInContext not supported in this language"); } - @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - throw new IllegalStateException("createAdvancedInstrumentRootFactory not supported in this language"); - } - public Node createFindContextNode0() { return createFindContextNode(); } diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java --- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java Thu Oct 08 16:48:42 2015 -0400 @@ -111,7 +111,7 @@ infoMessage.put(REPLMessage.BREAKPOINT_IGNORE_COUNT, Integer.toString(breakpoint.getIgnoreCount())); infoMessage.put(REPLMessage.INFO_VALUE, breakpoint.getLocationDescription().toString()); if (breakpoint.getCondition() != null) { - infoMessage.put(REPLMessage.BREAKPOINT_CONDITION, breakpoint.getCondition()); + infoMessage.put(REPLMessage.BREAKPOINT_CONDITION, breakpoint.getCondition().getCode()); } infoMessage.put(REPLMessage.STATUS, REPLMessage.SUCCEEDED); return infoMessage; diff -r 371045b1312d -r 260e3cdf11ec truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/ToolTestUtil.java --- a/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/ToolTestUtil.java Thu Oct 01 20:32:49 2015 +0200 +++ b/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/ToolTestUtil.java Thu Oct 08 16:48:42 2015 -0400 @@ -33,8 +33,6 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.instrument.ASTProber; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; import com.oracle.truffle.api.instrument.EventHandlerNode; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.KillException; @@ -139,11 +137,6 @@ } @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - return null; - } - - @Override protected Object createContext(Env env) { return null; }