From a3084c2f47ac4c89b9ae858397c60fc379f1bc7d Mon Sep 17 00:00:00 2001 From: poispois Date: Wed, 21 Oct 2020 07:39:05 +0900 Subject: [PATCH 1/8] WIP --- .../instrumentation/FieldReassignedEvent.java | 25 +++++++++++ .../instrumentation/InstrumentAccessor.java | 1 + .../instrumentation/ObjectChangeListener.java | 5 +++ .../api/instrumentation/ObjectTracker.java | 42 +++++++++++++++++++ .../oracle/truffle/object/PropertyImpl.java | 8 ++++ 5 files changed, 81 insertions(+) create mode 100644 truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/FieldReassignedEvent.java create mode 100644 truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectChangeListener.java create mode 100644 truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/FieldReassignedEvent.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/FieldReassignedEvent.java new file mode 100644 index 000000000000..f7e5a166df78 --- /dev/null +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/FieldReassignedEvent.java @@ -0,0 +1,25 @@ +package com.oracle.truffle.api.instrumentation; + +public class FieldReassignedEvent { + private final Object object; + private final Object key; + private final Object value; + + FieldReassignedEvent(Object object, Object key, Object value) { + this.object = object; + this.key = key; + this.value = value; + } + + public Object getObject() { + return object; + } + + public Object getKey() { + return key; + } + + public Object getValue() { + return value; + } +} diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java index 463e28fd0ec0..70e97f5ad123 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java @@ -181,6 +181,7 @@ public void collectEnvServices(Set collectTo, Object polyglotLanguage, T Instrumenter instrumenter = instrumentationHandler.forLanguage(language); collectTo.add(instrumenter); AllocationReporter allocationReporter = instrumentationHandler.getAllocationReporter(InstrumentAccessor.langAccess().getLanguageInfo(language)); + ObjectTracker objectTracker = new ObjectTracker(); // TODO collectTo.add(allocationReporter); } diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectChangeListener.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectChangeListener.java new file mode 100644 index 000000000000..53a7d6d27cba --- /dev/null +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectChangeListener.java @@ -0,0 +1,5 @@ +package com.oracle.truffle.api.instrumentation; + +public interface ObjectChangeListener { + void onFieldAssigned(FieldReassignedEvent e); +} diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java new file mode 100644 index 000000000000..6f6664f9d1fb --- /dev/null +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java @@ -0,0 +1,42 @@ +package com.oracle.truffle.api.instrumentation; + +import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.nodes.ExplodeLoop; + +import java.util.Arrays; + +public class ObjectTracker { + @CompilerDirectives.CompilationFinal(dimensions = 1) private volatile ObjectChangeListener[] listeners = null; + + public ObjectTracker() {} + + void addListener(ObjectChangeListener l) { + CompilerAsserts.neverPartOfCompilation(); + synchronized (this) { + if (listeners == null) { + listeners = new ObjectChangeListener[]{l}; + } else { + int i = listeners.length; + ObjectChangeListener[] newListeners = Arrays.copyOf(listeners, i + 1); + newListeners[i] = l; + listeners = newListeners; + } + } + } + + @ExplodeLoop + public void notifyAssignment(Object object, Object key, Object value) { + CompilerAsserts.partialEvaluationConstant(this); + + System.out.println("notifyAssignment: Object: " + object + " / Key: " + key + " Value: "); + + if (listeners != null) { + ObjectChangeListener[] ls = listeners; + FieldReassignedEvent e = new FieldReassignedEvent(object, key, value); + for (ObjectChangeListener listener : ls) { + listener.onFieldAssigned(e); + } + } + } +} diff --git a/truffle/src/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyImpl.java b/truffle/src/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyImpl.java index 67809348461e..aeccb4d2f4c2 100644 --- a/truffle/src/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyImpl.java +++ b/truffle/src/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyImpl.java @@ -172,6 +172,7 @@ private static boolean verifyShapeParameters(DynamicObject store, Shape oldShape @Override public final void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException { assert verifyShapeParameters(store, oldShape, newShape); + setReport(store, value); getLocation().set(store, value, oldShape, newShape); } @@ -180,6 +181,7 @@ public final void set(DynamicObject store, Object value, Shape oldShape, Shape n public final void setSafe(DynamicObject store, Object value, Shape oldShape, Shape newShape) { assert verifyShapeParameters(store, oldShape, newShape); try { + setReport(store, value); getLocation().set(store, value, oldShape, newShape); } catch (IncompatibleLocationException ex) { throw new IllegalStateException(); @@ -191,12 +193,18 @@ public final void setSafe(DynamicObject store, Object value, Shape oldShape, Sha public final void setGeneric(DynamicObject store, Object value, Shape oldShape, Shape newShape) { assert verifyShapeParameters(store, oldShape, newShape); try { + + setReport(store, value); getLocation().set(store, value, oldShape, newShape); } catch (IncompatibleLocationException ex) { setWithShapeSlowCase(store, value, oldShape, newShape); } } + private void setReport(DynamicObject obj, Object value) { + System.out.println("New value is set. Obj: " + obj.toString() + " / Key: " + key + " / Value:" + value.toString()); + } + /** @since 0.17 or earlier */ @Override public boolean equals(Object obj) { From 78c1f97a12c87ee633fa1bcb520c4e71d515713f Mon Sep 17 00:00:00 2001 From: poispois Date: Wed, 21 Oct 2020 16:59:51 +0900 Subject: [PATCH 2/8] Object tracking --- .../truffle/api/instrumentation/InstrumentAccessor.java | 1 + .../oracle/truffle/api/instrumentation/ObjectTracker.java | 2 +- .../src/com/oracle/truffle/object/PropertyImpl.java | 8 -------- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java index 70e97f5ad123..118efa65791a 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java @@ -183,6 +183,7 @@ public void collectEnvServices(Set collectTo, Object polyglotLanguage, T AllocationReporter allocationReporter = instrumentationHandler.getAllocationReporter(InstrumentAccessor.langAccess().getLanguageInfo(language)); ObjectTracker objectTracker = new ObjectTracker(); // TODO collectTo.add(allocationReporter); + collectTo.add(objectTracker); } @Override diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java index 6f6664f9d1fb..8d23da58de59 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java @@ -29,7 +29,7 @@ void addListener(ObjectChangeListener l) { public void notifyAssignment(Object object, Object key, Object value) { CompilerAsserts.partialEvaluationConstant(this); - System.out.println("notifyAssignment: Object: " + object + " / Key: " + key + " Value: "); + System.out.println("notifyAssignment: Object: " + object + " / Key: " + key + " Value: " + value); if (listeners != null) { ObjectChangeListener[] ls = listeners; diff --git a/truffle/src/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyImpl.java b/truffle/src/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyImpl.java index aeccb4d2f4c2..67809348461e 100644 --- a/truffle/src/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyImpl.java +++ b/truffle/src/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyImpl.java @@ -172,7 +172,6 @@ private static boolean verifyShapeParameters(DynamicObject store, Shape oldShape @Override public final void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException { assert verifyShapeParameters(store, oldShape, newShape); - setReport(store, value); getLocation().set(store, value, oldShape, newShape); } @@ -181,7 +180,6 @@ public final void set(DynamicObject store, Object value, Shape oldShape, Shape n public final void setSafe(DynamicObject store, Object value, Shape oldShape, Shape newShape) { assert verifyShapeParameters(store, oldShape, newShape); try { - setReport(store, value); getLocation().set(store, value, oldShape, newShape); } catch (IncompatibleLocationException ex) { throw new IllegalStateException(); @@ -193,18 +191,12 @@ public final void setSafe(DynamicObject store, Object value, Shape oldShape, Sha public final void setGeneric(DynamicObject store, Object value, Shape oldShape, Shape newShape) { assert verifyShapeParameters(store, oldShape, newShape); try { - - setReport(store, value); getLocation().set(store, value, oldShape, newShape); } catch (IncompatibleLocationException ex) { setWithShapeSlowCase(store, value, oldShape, newShape); } } - private void setReport(DynamicObject obj, Object value) { - System.out.println("New value is set. Obj: " + obj.toString() + " / Key: " + key + " / Value:" + value.toString()); - } - /** @since 0.17 or earlier */ @Override public boolean equals(Object obj) { From 672846cdf435f30746264085fcea5786d15e6176 Mon Sep 17 00:00:00 2001 From: poispois Date: Tue, 24 Nov 2020 16:13:46 +0900 Subject: [PATCH 3/8] temp --- .../com/oracle/truffle/api/instrumentation/ObjectTracker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java index 8d23da58de59..bafe0b2bff7e 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java @@ -11,7 +11,7 @@ public class ObjectTracker { public ObjectTracker() {} - void addListener(ObjectChangeListener l) { + public void addListener(ObjectChangeListener l) { CompilerAsserts.neverPartOfCompilation(); synchronized (this) { if (listeners == null) { From 5a7599b74cfe66e595b6f26046eb9503b40c2bb8 Mon Sep 17 00:00:00 2001 From: poispois Date: Tue, 1 Dec 2020 00:14:22 +0900 Subject: [PATCH 4/8] Add some methods to attach ObjectChangeListener --- .../api/instrumentation/EventBinding.java | 12 +++++ .../instrumentation/InstrumentAccessor.java | 2 +- .../InstrumentationHandler.java | 48 +++++++++++++++++++ .../api/instrumentation/Instrumenter.java | 2 + .../api/instrumentation/ObjectTracker.java | 37 ++++++++++++-- 5 files changed, 97 insertions(+), 4 deletions(-) diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/EventBinding.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/EventBinding.java index fa11c42a01bd..0ba93d52dbca 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/EventBinding.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/EventBinding.java @@ -308,4 +308,16 @@ AllocationEventFilter getAllocationFilter() { } + static final class ObjectChange extends EventBinding { + private final AllocationEventFilter filterObjectChange; + + ObjectChange(AbstractInstrumenter instrumenter, AllocationEventFilter filter, T lister) { + super(instrumenter, lister); + this.filterObjectChange = filter; + } + + AllocationEventFilter getAllocationFilter() { + return filterObjectChange; + } + } } diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java index 118efa65791a..2a8f4acb2079 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java @@ -181,7 +181,7 @@ public void collectEnvServices(Set collectTo, Object polyglotLanguage, T Instrumenter instrumenter = instrumentationHandler.forLanguage(language); collectTo.add(instrumenter); AllocationReporter allocationReporter = instrumentationHandler.getAllocationReporter(InstrumentAccessor.langAccess().getLanguageInfo(language)); - ObjectTracker objectTracker = new ObjectTracker(); // TODO + ObjectTracker objectTracker = instrumentationHandler.getObjectTracker(InstrumentAccessor.langAccess().getLanguageInfo(language)); collectTo.add(allocationReporter); collectTo.add(objectTracker); } diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentationHandler.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentationHandler.java index 5f015a5f942e..cb4747888b96 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentationHandler.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentationHandler.java @@ -141,6 +141,7 @@ final class InstrumentationHandler { final Collection loadedRoots = new WeakAsyncList<>(256); private final Collection executedRoots = new WeakAsyncList<>(64); private final Collection allocationReporters = new WeakAsyncList<>(16); + private final Collection objectTrackers = new WeakAsyncList<>(16); private volatile boolean hasLoadOrExecutionBinding = false; private final CopyOnWriteList> executionBindings = new CopyOnWriteList<>(new EventBinding.Source[0]); @@ -153,6 +154,7 @@ final class InstrumentationHandler { private final Collection> outputStdBindings = new EventBindingList<>(1); private final Collection> outputErrBindings = new EventBindingList<>(1); private final Collection> allocationBindings = new EventBindingList<>(2); + private final Collection> objectChangeBindings = new EventBindingList<>(2); private final Collection> contextsBindings = new EventBindingList<>(8); private final Collection> threadsBindings = new EventBindingList<>(8); private final Collection> threadsActivationBindings = new EventBindingList<>(8); @@ -543,6 +545,24 @@ private EventBinding addAllocationBinding(Even return binding; } + private EventBinding addObjectChangeBinding(EventBinding.ObjectChange binding) { + if (TRACE) { + trace("BEGIN: Adding allocation binding %s%n", binding.getElement()); + } + + this.objectChangeBindings.add(binding); + for (ObjectTracker objectTracker : objectTrackers) { + if (binding.getAllocationFilter().contains(objectTracker.language)) { + objectTracker.addListener(binding.getElement()); + } + } + + if (TRACE) { + trace("END: Added allocation binding %s%n", binding.getElement()); + } + return binding; + } + private EventBinding addContextsBinding(EventBinding binding, boolean includeActiveContexts) { if (TRACE) { trace("BEGIN: Adding contexts binding %s%n", binding.getElement()); @@ -683,6 +703,14 @@ void disposeBinding(EventBinding binding) { allocationReporter.removeListener(l); } } + } else if (binding instanceof EventBinding.ObjectChange) { + final EventBinding.ObjectChange objectChangeBinding = (EventBinding.ObjectChange) binding; + final ObjectChangeListener l = (ObjectChangeListener) binding.getElement(); + for (ObjectTracker objectTracker : objectTrackers) { + if (objectChangeBinding.getAllocationFilter().contains(objectTracker.language)) { + objectTracker.removeListener(l); + } + } } else { Object elm = binding.getElement(); if (elm instanceof OutputStream) { @@ -989,6 +1017,10 @@ private EventBinding attachAllocationListener( return addAllocationBinding(new EventBinding.Allocation<>(instrumenter, filter, listener)); } + private EventBinding attachObjectChangeListener(AbstractInstrumenter instrumenter, AllocationEventFilter filter, T listener) { + return addObjectChangeBinding(new EventBinding.ObjectChange<>(instrumenter, filter, listener)); + } + private EventBinding attachContextsListener(AbstractInstrumenter instrumenter, T listener, boolean includeActiveContexts) { assert listener != null; return addContextsBinding(new EventBinding<>(instrumenter, listener), includeActiveContexts); @@ -1266,6 +1298,17 @@ AllocationReporter getAllocationReporter(LanguageInfo info) { return allocationReporter; } + ObjectTracker getObjectTracker(LanguageInfo info) { + final ObjectTracker objectTracker = new ObjectTracker(info); + objectTrackers.add(objectTracker); + for (EventBinding.ObjectChange binding : objectChangeBindings) { + if (binding.getAllocationFilter().contains(info)) { + objectTracker.addListener(binding.getElement()); + } + } + return objectTracker; + } + void finalizeStore() { this.out = null; this.err = null; @@ -2502,6 +2545,11 @@ public EventBinding attachAllocationListener(A return InstrumentationHandler.this.attachAllocationListener(this, filter, listener); } + @Override + public EventBinding attachObjectChangeListener(AllocationEventFilter filter, T listener) { + return InstrumentationHandler.this.attachObjectChangeListener(this, filter, listener); + } + @Override public EventBinding attachOutConsumer(T stream) { return InstrumentationHandler.this.attachOutputConsumer(this, stream, false); diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/Instrumenter.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/Instrumenter.java index e501a0886458..51a5588c7e35 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/Instrumenter.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/Instrumenter.java @@ -301,6 +301,8 @@ public final EventBinding attachExecuti */ public abstract EventBinding attachAllocationListener(AllocationEventFilter filter, T listener); + public abstract EventBinding attachObjectChangeListener(AllocationEventFilter filter, T listener); + /** * Attach a {@link ContextsListener listener} to be notified about changes in contexts in guest * language application. This is supported in {@link TruffleInstrument.Env#getInstrumenter()} diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java index bafe0b2bff7e..7144a8f1c9d1 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java @@ -3,13 +3,18 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.nodes.ExplodeLoop; +import com.oracle.truffle.api.nodes.LanguageInfo; import java.util.Arrays; public class ObjectTracker { @CompilerDirectives.CompilationFinal(dimensions = 1) private volatile ObjectChangeListener[] listeners = null; - public ObjectTracker() {} + final LanguageInfo language; + + public ObjectTracker(LanguageInfo language) { + this.language = language; + } public void addListener(ObjectChangeListener l) { CompilerAsserts.neverPartOfCompilation(); @@ -25,12 +30,38 @@ public void addListener(ObjectChangeListener l) { } } + void removeListener(ObjectChangeListener l) { + CompilerAsserts.neverPartOfCompilation(); + synchronized (this) { + final int len = listeners.length; + if (len == 1) { + if (listeners[0] == l) { + listeners = null; + } + } else { + for (int i = 0; i < len; i++) { + if (listeners[i] == l) { + if (i == (len - 1)) { + listeners = Arrays.copyOf(listeners, i); + } else if (i == 0) { + listeners = Arrays.copyOfRange(listeners, 1, len); + } else { + ObjectChangeListener[] newListeners = new ObjectChangeListener[len - 1]; + System.arraycopy(listeners, 0, newListeners, 0, i); + System.arraycopy(listeners, i + 1, newListeners, i, len - i - 1); + listeners = newListeners; + } + break; + } + } + } + } + } + @ExplodeLoop public void notifyAssignment(Object object, Object key, Object value) { CompilerAsserts.partialEvaluationConstant(this); - System.out.println("notifyAssignment: Object: " + object + " / Key: " + key + " Value: " + value); - if (listeners != null) { ObjectChangeListener[] ls = listeners; FieldReassignedEvent e = new FieldReassignedEvent(object, key, value); From 16fbfc5e623305901367f77b0ec47dfa58ef9a63 Mon Sep 17 00:00:00 2001 From: poispois Date: Wed, 2 Dec 2020 02:17:41 +0900 Subject: [PATCH 5/8] Rename some classes --- .../{FieldReassignedEvent.java => ObjectChangeEvent.java} | 4 ++-- .../truffle/api/instrumentation/ObjectChangeListener.java | 2 +- .../com/oracle/truffle/api/instrumentation/ObjectTracker.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/{FieldReassignedEvent.java => ObjectChangeEvent.java} (79%) diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/FieldReassignedEvent.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectChangeEvent.java similarity index 79% rename from truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/FieldReassignedEvent.java rename to truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectChangeEvent.java index f7e5a166df78..19b05f910e96 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/FieldReassignedEvent.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectChangeEvent.java @@ -1,11 +1,11 @@ package com.oracle.truffle.api.instrumentation; -public class FieldReassignedEvent { +public class ObjectChangeEvent { private final Object object; private final Object key; private final Object value; - FieldReassignedEvent(Object object, Object key, Object value) { + ObjectChangeEvent(Object object, Object key, Object value) { this.object = object; this.key = key; this.value = value; diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectChangeListener.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectChangeListener.java index 53a7d6d27cba..f214d90b66bd 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectChangeListener.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectChangeListener.java @@ -1,5 +1,5 @@ package com.oracle.truffle.api.instrumentation; public interface ObjectChangeListener { - void onFieldAssigned(FieldReassignedEvent e); + void onFieldAssigned(ObjectChangeEvent e); } diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java index 7144a8f1c9d1..3fbe6f5728a7 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java @@ -64,7 +64,7 @@ public void notifyAssignment(Object object, Object key, Object value) { if (listeners != null) { ObjectChangeListener[] ls = listeners; - FieldReassignedEvent e = new FieldReassignedEvent(object, key, value); + ObjectChangeEvent e = new ObjectChangeEvent(object, key, value); for (ObjectChangeListener listener : ls) { listener.onFieldAssigned(e); } From 07a6010231dcb9b08afbfed7be3c4e84d3553b22 Mon Sep 17 00:00:00 2001 From: poispois Date: Mon, 17 May 2021 22:42:35 +0900 Subject: [PATCH 6/8] Add StackTracker --- .../api/instrumentation/EventBinding.java | 13 ++ .../instrumentation/InstrumentAccessor.java | 2 + .../InstrumentationHandler.java | 49 ++++++ .../api/instrumentation/Instrumenter.java | 2 + .../api/instrumentation/ObjectTracker.java | 2 +- .../api/instrumentation/StackListener.java | 19 +++ .../api/instrumentation/StackTracker.java | 145 ++++++++++++++++++ 7 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/StackListener.java create mode 100644 truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/StackTracker.java diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/EventBinding.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/EventBinding.java index 0ba93d52dbca..883f46d3ee44 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/EventBinding.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/EventBinding.java @@ -320,4 +320,17 @@ AllocationEventFilter getAllocationFilter() { return filterObjectChange; } } + + static final class StackTracking extends EventBinding { + private final AllocationEventFilter filterObjectChange; + + StackTracking(AbstractInstrumenter instrumenter, AllocationEventFilter filter, T lister) { + super(instrumenter, lister); + this.filterObjectChange = filter; + } + + AllocationEventFilter getAllocationFilter() { + return filterObjectChange; + } + } } diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java index 2a8f4acb2079..fb40b0e80b53 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentAccessor.java @@ -182,8 +182,10 @@ public void collectEnvServices(Set collectTo, Object polyglotLanguage, T collectTo.add(instrumenter); AllocationReporter allocationReporter = instrumentationHandler.getAllocationReporter(InstrumentAccessor.langAccess().getLanguageInfo(language)); ObjectTracker objectTracker = instrumentationHandler.getObjectTracker(InstrumentAccessor.langAccess().getLanguageInfo(language)); + StackTracker stackTracker = instrumentationHandler.getStackTracker(InstrumentAccessor.langAccess().getLanguageInfo(language)); collectTo.add(allocationReporter); collectTo.add(objectTracker); + collectTo.add(stackTracker); } @Override diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentationHandler.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentationHandler.java index cb4747888b96..12a90a2c8c51 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentationHandler.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/InstrumentationHandler.java @@ -142,6 +142,8 @@ final class InstrumentationHandler { private final Collection executedRoots = new WeakAsyncList<>(64); private final Collection allocationReporters = new WeakAsyncList<>(16); private final Collection objectTrackers = new WeakAsyncList<>(16); + private final Collection stackTrackers = new WeakAsyncList<>(16); + private volatile boolean hasLoadOrExecutionBinding = false; private final CopyOnWriteList> executionBindings = new CopyOnWriteList<>(new EventBinding.Source[0]); @@ -155,6 +157,7 @@ final class InstrumentationHandler { private final Collection> outputErrBindings = new EventBindingList<>(1); private final Collection> allocationBindings = new EventBindingList<>(2); private final Collection> objectChangeBindings = new EventBindingList<>(2); + private final Collection> stackTrackingBindings = new EventBindingList<>(2); private final Collection> contextsBindings = new EventBindingList<>(8); private final Collection> threadsBindings = new EventBindingList<>(8); private final Collection> threadsActivationBindings = new EventBindingList<>(8); @@ -563,6 +566,24 @@ private EventBinding addObjectChangeBinding( return binding; } + private EventBinding addStackTrackingBinding(EventBinding.StackTracking binding) { + if (TRACE) { + trace("BEGIN: Adding allocation binding %s%n", binding.getElement()); + } + + this.stackTrackingBindings.add(binding); + for (StackTracker stackTracker : stackTrackers) { + if (binding.getAllocationFilter().contains(stackTracker.language)) { + stackTracker.addListener(binding.getElement()); + } + } + + if (TRACE) { + trace("END: Added allocation binding %s%n", binding.getElement()); + } + return binding; + } + private EventBinding addContextsBinding(EventBinding binding, boolean includeActiveContexts) { if (TRACE) { trace("BEGIN: Adding contexts binding %s%n", binding.getElement()); @@ -711,6 +732,14 @@ void disposeBinding(EventBinding binding) { objectTracker.removeListener(l); } } + } else if (binding instanceof EventBinding.StackTracking) { + final EventBinding.StackTracking stackTrackingBinding = (EventBinding.StackTracking) binding; + final StackListener l = (StackListener) binding.getElement(); + for (StackTracker stackTracker : stackTrackers) { + if (stackTrackingBinding.getAllocationFilter().contains(stackTracker.language)) { + stackTracker.removeListener(l); + } + } } else { Object elm = binding.getElement(); if (elm instanceof OutputStream) { @@ -1021,6 +1050,10 @@ private EventBinding attachObjectChangeListe return addObjectChangeBinding(new EventBinding.ObjectChange<>(instrumenter, filter, listener)); } + private EventBinding attachStackListener(AbstractInstrumenter instrumenter, AllocationEventFilter filter, T listener) { + return addStackTrackingBinding(new EventBinding.StackTracking<>(instrumenter, filter, listener)); + } + private EventBinding attachContextsListener(AbstractInstrumenter instrumenter, T listener, boolean includeActiveContexts) { assert listener != null; return addContextsBinding(new EventBinding<>(instrumenter, listener), includeActiveContexts); @@ -1309,6 +1342,17 @@ ObjectTracker getObjectTracker(LanguageInfo info) { return objectTracker; } + StackTracker getStackTracker(LanguageInfo info) { + final StackTracker stackTracker = new StackTracker(info); + stackTrackers.add(stackTracker); + for (EventBinding.StackTracking binding : stackTrackingBindings) { + if (binding.getAllocationFilter().contains(info)) { + stackTracker.addListener(binding.getElement()); + } + } + return stackTracker; + } + void finalizeStore() { this.out = null; this.err = null; @@ -2550,6 +2594,11 @@ public EventBinding attachObjectChangeListen return InstrumentationHandler.this.attachObjectChangeListener(this, filter, listener); } + @Override + public EventBinding attachStackListener(AllocationEventFilter filter, T listener) { + return InstrumentationHandler.this.attachStackListener(this, filter, listener); + } + @Override public EventBinding attachOutConsumer(T stream) { return InstrumentationHandler.this.attachOutputConsumer(this, stream, false); diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/Instrumenter.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/Instrumenter.java index 51a5588c7e35..d2660cfba03b 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/Instrumenter.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/Instrumenter.java @@ -303,6 +303,8 @@ public final EventBinding attachExecuti public abstract EventBinding attachObjectChangeListener(AllocationEventFilter filter, T listener); + public abstract EventBinding attachStackListener(AllocationEventFilter filter, T listener); + /** * Attach a {@link ContextsListener listener} to be notified about changes in contexts in guest * language application. This is supported in {@link TruffleInstrument.Env#getInstrumenter()} diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java index 3fbe6f5728a7..941b192f1f04 100644 --- a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/ObjectTracker.java @@ -30,7 +30,7 @@ public void addListener(ObjectChangeListener l) { } } - void removeListener(ObjectChangeListener l) { + public void removeListener(ObjectChangeListener l) { CompilerAsserts.neverPartOfCompilation(); synchronized (this) { final int len = listeners.length; diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/StackListener.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/StackListener.java new file mode 100644 index 000000000000..e3e1a091c1b5 --- /dev/null +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/StackListener.java @@ -0,0 +1,19 @@ +package com.oracle.truffle.api.instrumentation; + +import com.oracle.truffle.api.frame.FrameSlot; + +public interface StackListener { + public void onObjectSet(FrameSlot slot, Object value); + + public void onBooleanSet(FrameSlot slot, boolean value); + + public void onByteSet(FrameSlot slot, byte value); + + public void onIntSet(FrameSlot slot, int value); + + public void onLongSet(FrameSlot slot, long value); + + public void onFloatSet(FrameSlot slot, float value); + + public void onDoubleSet(FrameSlot slot, double value); +} diff --git a/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/StackTracker.java b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/StackTracker.java new file mode 100644 index 000000000000..475665cc3230 --- /dev/null +++ b/truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/StackTracker.java @@ -0,0 +1,145 @@ +package com.oracle.truffle.api.instrumentation; + +import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.frame.FrameSlot; +import com.oracle.truffle.api.nodes.ExplodeLoop; +import com.oracle.truffle.api.nodes.LanguageInfo; + +import java.util.Arrays; + +public class StackTracker { + @CompilerDirectives.CompilationFinal(dimensions = 1) private volatile StackListener[] listeners = null; + + final LanguageInfo language; + + public StackTracker(LanguageInfo language) { + this.language = language; + } + + public void addListener(StackListener l) { + CompilerAsserts.neverPartOfCompilation(); + synchronized (this) { + if (listeners == null) { + listeners = new StackListener[]{l}; + } else { + int i = listeners.length; + StackListener[] newListeners = Arrays.copyOf(listeners, i + 1); + newListeners[i] = l; + listeners = newListeners; + } + } + } + + public void removeListener(StackListener l) { + CompilerAsserts.neverPartOfCompilation(); + synchronized (this) { + final int len = listeners.length; + if (len == 1) { + if (listeners[0] == l) { + listeners = null; + } + } else { + for (int i = 0; i < len; i++) { + if (listeners[i] == l) { + if (i == (len - 1)) { + listeners = Arrays.copyOf(listeners, i); + } else if (i == 0) { + listeners = Arrays.copyOfRange(listeners, 1, len); + } else { + StackListener[] newListeners = new StackListener[len - 1]; + System.arraycopy(listeners, 0, newListeners, 0, i); + System.arraycopy(listeners, i + 1, newListeners, i, len - i - 1); + listeners = newListeners; + } + break; + } + } + } + } + } + + @ExplodeLoop + public void notifyBooleanSet(FrameSlot slot, boolean value) { + CompilerAsserts.partialEvaluationConstant(this); + + if (listeners != null) { + StackListener[] ls = listeners; + for (StackListener listener : ls) { + listener.onBooleanSet(slot, value); + } + } + } + + @ExplodeLoop + public void notifyByteSet(FrameSlot slot, byte value) { + CompilerAsserts.partialEvaluationConstant(this); + + if (listeners != null) { + StackListener[] ls = listeners; + for (StackListener listener : ls) { + listener.onByteSet(slot, value); + } + } + } + + @ExplodeLoop + public void notifyIntSet(FrameSlot slot, int value) { + CompilerAsserts.partialEvaluationConstant(this); + + if (listeners != null) { + StackListener[] ls = listeners; + for (StackListener listener : ls) { + listener.onIntSet(slot, value); + } + } + } + + @ExplodeLoop + public void notifyLongSet(FrameSlot slot, long value) { + CompilerAsserts.partialEvaluationConstant(this); + + if (listeners != null) { + StackListener[] ls = listeners; + for (StackListener listener : ls) { + listener.onLongSet(slot, value); + } + } + } + + @ExplodeLoop + public void notifyFloatSet(FrameSlot slot, float value) { + CompilerAsserts.partialEvaluationConstant(this); + + if (listeners != null) { + StackListener[] ls = listeners; + for (StackListener listener : ls) { + listener.onFloatSet(slot, value); + } + } + } + + @ExplodeLoop + public void notifyDoubleSet(FrameSlot slot, double value) { + CompilerAsserts.partialEvaluationConstant(this); + + if (listeners != null) { + StackListener[] ls = listeners; + for (StackListener listener : ls) { + listener.onDoubleSet(slot, value); + } + } + } + + @ExplodeLoop + public void notifyObjectSet(FrameSlot slot, Object value) { + CompilerAsserts.partialEvaluationConstant(this); + + if (listeners != null) { + StackListener[] ls = listeners; + for (StackListener listener : ls) { + listener.onObjectSet(slot, value); + } + } + } +} From 4dbb7d3da95e376412507b62a751dfcf4ec61210 Mon Sep 17 00:00:00 2001 From: Shusuke Takahashi Date: Wed, 27 Jul 2022 23:37:18 +0900 Subject: [PATCH 7/8] wip --- .../src/com/oracle/truffle/sl/SLLanguage.java | 14 +++++++- .../truffle/sl/builtins/SLBuiltinNode.java | 4 +++ .../sl/builtins/SLDefineFunctionBuiltin.java | 7 ++++ .../truffle/sl/builtins/SLEvalBuiltin.java | 11 ++++++ .../truffle/sl/builtins/SLGetSizeBuiltin.java | 7 ++++ .../truffle/sl/builtins/SLHasSizeBuiltin.java | 8 +++++ .../builtins/SLHelloEqualsWorldBuiltin.java | 7 ++++ .../truffle/sl/builtins/SLImportBuiltin.java | 5 +++ .../sl/builtins/SLIsExecutableBuiltin.java | 7 ++++ .../sl/builtins/SLIsInstanceBuiltin.java | 10 ++++++ .../truffle/sl/builtins/SLIsNullBuiltin.java | 7 ++++ .../sl/builtins/SLNanoTimeBuiltin.java | 6 ++++ .../sl/builtins/SLNewObjectBuiltin.java | 7 ++++ .../truffle/sl/builtins/SLPrintlnBuiltin.java | 7 ++++ .../truffle/sl/builtins/SLReadlnBuiltin.java | 6 ++++ .../sl/builtins/SLStackTraceBuiltin.java | 6 ++++ .../truffle/sl/builtins/SLTypeOfBuiltin.java | 6 ++++ .../sl/builtins/SLWrapPrimitiveBuiltin.java | 7 ++++ .../oracle/truffle/sl/nodes/SLBinaryNode.java | 2 ++ .../truffle/sl/nodes/SLStatementNode.java | 1 + .../sl/nodes/controlflow/SLBlockNode.java | 15 ++++++++ .../sl/nodes/controlflow/SLBreakNode.java | 5 +++ .../sl/nodes/controlflow/SLContinueNode.java | 5 +++ .../sl/nodes/controlflow/SLDebuggerNode.java | 4 +++ .../nodes/controlflow/SLFunctionBodyNode.java | 6 ++++ .../sl/nodes/controlflow/SLIfNode.java | 9 +++++ .../sl/nodes/controlflow/SLReturnNode.java | 7 ++++ .../sl/nodes/controlflow/SLWhileNode.java | 8 +++++ .../controlflow/SLWhileRepeatingNode.java | 7 ++++ .../sl/nodes/expression/SLAddNode.java | 10 ++++++ .../expression/SLBigIntegerLiteralNode.java | 7 ++++ .../sl/nodes/expression/SLDivNode.java | 10 ++++++ .../sl/nodes/expression/SLEqualNode.java | 9 +++++ .../expression/SLFunctionLiteralNode.java | 9 +++++ .../sl/nodes/expression/SLInvokeNode.java | 12 +++++++ .../nodes/expression/SLLessOrEqualNode.java | 10 ++++++ .../sl/nodes/expression/SLLessThanNode.java | 9 +++++ .../sl/nodes/expression/SLLogicalAndNode.java | 8 +++++ .../sl/nodes/expression/SLLogicalNotNode.java | 8 +++++ .../sl/nodes/expression/SLLogicalOrNode.java | 8 +++++ .../nodes/expression/SLLongLiteralNode.java | 7 ++++ .../sl/nodes/expression/SLMulNode.java | 10 ++++++ .../expression/SLParenExpressionNode.java | 7 ++++ .../nodes/expression/SLReadPropertyNode.java | 11 ++++++ .../nodes/expression/SLShortCircuitNode.java | 4 +-- .../nodes/expression/SLStringLiteralNode.java | 7 ++++ .../sl/nodes/expression/SLSubNode.java | 8 +++++ .../nodes/expression/SLWritePropertyNode.java | 34 ++++++++++++++++--- .../sl/nodes/local/SLReadArgumentNode.java | 7 ++++ .../nodes/local/SLReadLocalVariableNode.java | 7 ++++ .../nodes/local/SLWriteLocalVariableNode.java | 19 +++++++++-- .../truffle/sl/nodes/util/SLUnboxNode.java | 6 ++++ .../oracle/truffle/sl/runtime/SLContext.java | 14 ++++++++ 53 files changed, 431 insertions(+), 11 deletions(-) diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java index 29d43061915f..b9c4d05db426 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java @@ -48,6 +48,7 @@ import com.oracle.truffle.api.Assumption; import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleLanguage; @@ -210,6 +211,8 @@ public final class SLLanguage extends TruffleLanguage { private final Shape rootShape; + @CompilerDirectives.CompilationFinal private SLContext context; + public SLLanguage() { counter++; this.rootShape = Shape.newBuilder().layout(SLObject.class).build(); @@ -217,7 +220,12 @@ public SLLanguage() { @Override protected SLContext createContext(Env env) { - return new SLContext(this, env, new ArrayList<>(EXTERNAL_BUILTINS)); + SLContext context = this.context; + if (context == null) { + this.context = context = new SLContext(this, env, new ArrayList<>(EXTERNAL_BUILTINS)); + } + + return context; } public RootCallTarget getOrCreateUndefinedFunction(String name) { @@ -367,6 +375,10 @@ protected Object getLanguageView(SLContext context, Object value) { return SLLanguageView.create(value); } + public SLContext getContext() { + return context; + } + /* * Still necessary for the old SL TCK to pass. We should remove with the old TCK. New language * should not override this. diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLBuiltinNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLBuiltinNode.java index 8c4bf0f0062c..ddaf59bab458 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLBuiltinNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLBuiltinNode.java @@ -47,6 +47,7 @@ import com.oracle.truffle.api.nodes.UnexpectedResultException; import com.oracle.truffle.sl.SLException; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLContext; import com.oracle.truffle.sl.runtime.SLFunctionRegistry; @@ -62,6 +63,8 @@ @GenerateNodeFactory public abstract class SLBuiltinNode extends SLExpressionNode { + protected abstract SLExpressionNode[] getArguments(); + @Override public final Object executeGeneric(VirtualFrame frame) { try { @@ -87,4 +90,5 @@ public final void executeVoid(VirtualFrame frame) { } protected abstract Object execute(VirtualFrame frame); + } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java index 6c3b7a8ce0a4..4ffa4e0db715 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java @@ -46,6 +46,7 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.sl.SLLanguage; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLContext; /** @@ -67,4 +68,10 @@ public String defineFunction(String code, @CachedContext(SLLanguage.class) SLCon return code; } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLDefineFunctionBuiltin)) return false; + return getArguments()[0].isEqualNode(((SLDefineFunctionBuiltin) that).getArguments()[0]); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLEvalBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLEvalBuiltin.java index a70383ea600a..f44f2ac8ce8b 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLEvalBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLEvalBuiltin.java @@ -49,6 +49,8 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.sl.SLLanguage; +import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLContext; /** @@ -88,4 +90,13 @@ protected CallTarget parse(String id, String code, SLContext context) { protected static boolean stringsEqual(String a, String b) { return a.equals(b); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLEvalBuiltin)) return false; + SLExpressionNode[] thisArgs = getArguments(); + SLExpressionNode[] thatArgs = ((SLEvalBuiltin) that).getArguments(); + return thisArgs[0].isEqualNode(thatArgs[0]) + && thisArgs[1].isEqualNode(thatArgs[1]); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLGetSizeBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLGetSizeBuiltin.java index f4cf751a57bd..54d27f7399dc 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLGetSizeBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLGetSizeBuiltin.java @@ -46,6 +46,7 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLException; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Built-in function that queries the size property of a foreign object. See @@ -62,4 +63,10 @@ public Object getSize(Object obj, @CachedLibrary("obj") InteropLibrary arrays) { throw new SLException("Element is not a valid array.", this); } } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLGetSizeBuiltin)) return false; + return getArguments()[0].isEqualNode(((SLGetSizeBuiltin) that).getArguments()[0]); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHasSizeBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHasSizeBuiltin.java index 88bef95099b6..20e3c83a38a6 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHasSizeBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHasSizeBuiltin.java @@ -44,6 +44,7 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Built-in function that queries if the foreign object has a size. See @@ -56,4 +57,11 @@ public abstract class SLHasSizeBuiltin extends SLBuiltinNode { public boolean hasSize(Object obj, @CachedLibrary("obj") InteropLibrary arrays) { return arrays.hasArrayElements(obj); } + + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLHasSizeBuiltin)) return false; + return getArguments()[0].isEqualNode(((SLHasSizeBuiltin) that).getArguments()[0]); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java index 3feec8cd091d..9d3bda39d7ed 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java @@ -48,6 +48,7 @@ import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * This builtin sets the variable named "hello" in the caller frame to the string "world". @@ -64,4 +65,10 @@ public String change() { frame.setObject(slot, "world"); return "world"; } + + @Override + public boolean isEqualNode(SLStatementNode that) { + return that instanceof SLHelloEqualsWorldBuiltin; + + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLImportBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLImportBuiltin.java index 27f756dc54bd..ccb2a4f5bc65 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLImportBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLImportBuiltin.java @@ -49,6 +49,7 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLException; import com.oracle.truffle.sl.SLLanguage; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLContext; import com.oracle.truffle.sl.runtime.SLNull; @@ -71,4 +72,8 @@ public Object importSymbol(String symbol, } } + @Override + public boolean isEqualNode(SLStatementNode that) { + return that instanceof SLImportBuiltin; // TODO + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsExecutableBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsExecutableBuiltin.java index 97697a1a48c2..ab49306e03e7 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsExecutableBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsExecutableBuiltin.java @@ -44,6 +44,7 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Built-in function that queries if the foreign object is executable. See @@ -56,4 +57,10 @@ public abstract class SLIsExecutableBuiltin extends SLBuiltinNode { public boolean isExecutable(Object obj, @CachedLibrary("obj") InteropLibrary executables) { return executables.isExecutable(obj); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLIsExecutableBuiltin)) return false; + return getArguments()[0].isEqualNode(((SLIsExecutableBuiltin) that).getArguments()[0]); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsInstanceBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsInstanceBuiltin.java index b1ad20cf50ef..2ac4e45d4b0c 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsInstanceBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsInstanceBuiltin.java @@ -47,6 +47,8 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Built-in function that returns true if the given operand is of a given meta-object. Meta-objects @@ -66,4 +68,12 @@ public Object doDefault(Object metaObject, Object value, } } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLIsInstanceBuiltin)) return false; + SLExpressionNode[] thisArgs = getArguments(); + SLExpressionNode[] thatArgs = ((SLIsInstanceBuiltin) that).getArguments(); + return thisArgs[0].isEqualNode(thatArgs[0]) + && thisArgs[1].isEqualNode(thatArgs[1]); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsNullBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsNullBuiltin.java index 9d452f15a0e0..5105b6c598b7 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsNullBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLIsNullBuiltin.java @@ -44,6 +44,7 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Built-in function that queries if the foreign object is a null value. See @@ -56,4 +57,10 @@ public abstract class SLIsNullBuiltin extends SLBuiltinNode { public boolean isExecutable(Object obj, @CachedLibrary("obj") InteropLibrary values) { return values.isNull(obj); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLIsNullBuiltin)) return false; + return getArguments()[0].isEqualNode(((SLIsNullBuiltin) that).getArguments()[0]); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNanoTimeBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNanoTimeBuiltin.java index 733d29fb1e14..644d5343cab9 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNanoTimeBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNanoTimeBuiltin.java @@ -42,6 +42,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Builtin function that returns the value of a high-resolution time, in nanoseconds. @@ -53,4 +54,9 @@ public abstract class SLNanoTimeBuiltin extends SLBuiltinNode { public long nanoTime() { return System.nanoTime(); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + return that instanceof SLNanoTimeBuiltin; + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNewObjectBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNewObjectBuiltin.java index bddffe788af6..3b69c6f36ef2 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNewObjectBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNewObjectBuiltin.java @@ -53,6 +53,7 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLLanguage; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLContext; import com.oracle.truffle.sl.runtime.SLNull; import com.oracle.truffle.sl.runtime.SLUndefinedNameException; @@ -81,4 +82,10 @@ public Object newObject(Object obj, @CachedLibrary("obj") InteropLibrary values) throw SLUndefinedNameException.undefinedFunction(this, obj); } } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLNewObjectBuiltin)) return false; + return getArguments()[0].isEqualNode(((SLNewObjectBuiltin) that).getArguments()[0]); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java index 8c50ce75e029..d50cc272961d 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java @@ -47,6 +47,8 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLLanguage; +import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLContext; import com.oracle.truffle.sl.runtime.SLLanguageView; @@ -71,4 +73,9 @@ public Object println(Object value, return value; } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLPrintlnBuiltin)) return false; + return getArguments()[0].isEqualNode(((SLPrintlnBuiltin) that).getArguments()[0]); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java index 291311e884ad..8c542594e0fb 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java @@ -49,6 +49,7 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLException; import com.oracle.truffle.sl.SLLanguage; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLContext; /** @@ -79,4 +80,9 @@ private String doRead(BufferedReader in) { throw new SLException(ex.getMessage(), this); } } + + @Override + public boolean isEqualNode(SLStatementNode that) { + return that instanceof SLReadlnBuiltin; + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java index 3753979ea69a..a4b2262631d9 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java @@ -53,6 +53,7 @@ import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Returns a string representation of the current stack. This includes the {@link CallTarget}s and @@ -99,4 +100,9 @@ public Integer visitFrame(FrameInstance frameInstance) { }); return str.toString(); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + return that instanceof SLStackTraceBuiltin; + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLTypeOfBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLTypeOfBuiltin.java index 930f1ecd2646..a8222c48ce16 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLTypeOfBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLTypeOfBuiltin.java @@ -45,6 +45,7 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLNull; import com.oracle.truffle.sl.runtime.SLType; @@ -70,4 +71,9 @@ public Object doDefault(Object operand, return SLNull.SINGLETON; } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLTypeOfBuiltin)) return false; + return getArguments()[0].isEqualNode(((SLTypeOfBuiltin) that).getArguments()[0]); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLWrapPrimitiveBuiltin.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLWrapPrimitiveBuiltin.java index da8f5d64a0fa..ae38a8caba88 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLWrapPrimitiveBuiltin.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLWrapPrimitiveBuiltin.java @@ -49,6 +49,7 @@ import com.oracle.truffle.api.library.Message; import com.oracle.truffle.api.library.ReflectionLibrary; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Builtin function to wrap primitive values in order to increase coverage of the Truffle TCK test. @@ -84,4 +85,10 @@ Object send(Message message, Object[] args, } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLWrapPrimitiveBuiltin)) return false; + return getArguments()[0].isEqualNode(((SLWrapPrimitiveBuiltin) that).getArguments()[0]); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java index 72f4820ccf2e..275a86c8a294 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java @@ -50,4 +50,6 @@ @NodeChild("leftNode") @NodeChild("rightNode") public abstract class SLBinaryNode extends SLExpressionNode { + protected abstract SLExpressionNode getLeftNode(); + protected abstract SLExpressionNode getRightNode(); } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java index 02c60db89083..ae4e029d1407 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java @@ -213,4 +213,5 @@ public static String formatSourceSection(Node node) { } } + public abstract boolean isEqualNode(SLStatementNode that); } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java index 16be90e27862..2535d6aa6d6e 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java @@ -129,6 +129,21 @@ public void executeVoid(VirtualFrame frame, SLStatementNode node, int index, int node.executeVoid(frame); } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLBlockNode)) return false; + SLBlockNode thatNode = (SLBlockNode) that; + SLStatementNode[] thisChildren = block.getElements(); + SLStatementNode[] thatChildren = thatNode.block.getElements(); + if (thisChildren.length != thatChildren.length) return false; + + for (int i = 0; i < thisChildren.length; i++) { + if (!thisChildren[i].isEqualNode(thatChildren[i])) return false; + } + + return true; + } + /** * All declared local variables accessible in this block. Variables declared in parent blocks * are included. diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakNode.java index 16c874e6c86c..c9d86605f13d 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakNode.java @@ -57,4 +57,9 @@ public final class SLBreakNode extends SLStatementNode { public void executeVoid(VirtualFrame frame) { throw SLBreakException.SINGLETON; } + + @Override + public boolean isEqualNode(SLStatementNode that) { + return that instanceof SLBreakNode; + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueNode.java index 740c2ee895c8..9edb8db3af63 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueNode.java @@ -57,4 +57,9 @@ public final class SLContinueNode extends SLStatementNode { public void executeVoid(VirtualFrame frame) { throw SLContinueException.SINGLETON; } + + @Override + public boolean isEqualNode(SLStatementNode that) { + return that instanceof SLContinueNode; + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLDebuggerNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLDebuggerNode.java index 73248c49a332..0d74f21a2c22 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLDebuggerNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLDebuggerNode.java @@ -65,4 +65,8 @@ public boolean hasTag(Class tag) { return super.hasTag(tag); } + @Override + public boolean isEqualNode(SLStatementNode that) { + return that instanceof SLDebuggerNode; + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java index ece6f45ba376..37677645311e 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java @@ -98,4 +98,10 @@ public Object executeGeneric(VirtualFrame frame) { /* Return the default null value. */ return SLNull.SINGLETON; } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLFunctionBodyNode)) return false; + return bodyNode.isEqualNode(((SLFunctionBodyNode) that).bodyNode); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java index 34de0d20b22a..cd141a2da75d 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java @@ -97,6 +97,15 @@ public void executeVoid(VirtualFrame frame) { } } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLIfNode)) return false; + SLIfNode thatIf = (SLIfNode) that; + return conditionNode.isEqualNode(thatIf.conditionNode) + && thenPartNode.isEqualNode(thatIf.thenPartNode) + && (elsePartNode == null ? thatIf.elsePartNode == null : elsePartNode.isEqualNode(thatIf.elsePartNode)); + } + private boolean evaluateCondition(VirtualFrame frame) { try { /* diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java index 08614651413f..f19482cfadf2 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java @@ -75,4 +75,11 @@ public void executeVoid(VirtualFrame frame) { } throw new SLReturnException(result); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLReturnNode)) return false; + SLReturnNode thatReturn = (SLReturnNode) that; + return valueNode == null ? thatReturn.valueNode == null : valueNode.isEqualNode(thatReturn.valueNode); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java index 55fd1aa85b17..53334df919c5 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java @@ -61,4 +61,12 @@ public void executeVoid(VirtualFrame frame) { loopNode.execute(frame); } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLWhileNode)) return false; + SLWhileRepeatingNode thisRep = (SLWhileRepeatingNode) loopNode.getRepeatingNode(); + SLWhileRepeatingNode thatRep = (SLWhileRepeatingNode) ((SLWhileNode) that).loopNode.getRepeatingNode(); + return thisRep.getConditionNode().isEqualNode(thatRep.getConditionNode()) + && thisRep.getBodyNode().isEqualNode(thatRep.getBodyNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileRepeatingNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileRepeatingNode.java index 4606485d9350..a7b08026751b 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileRepeatingNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileRepeatingNode.java @@ -130,4 +130,11 @@ public String toString() { return SLStatementNode.formatSourceSection(this); } + SLExpressionNode getConditionNode() { + return conditionNode; + } + + SLStatementNode getBodyNode() { + return bodyNode; + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java index fe29e8297551..420a5916faa4 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java @@ -47,6 +47,8 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLException; import com.oracle.truffle.sl.nodes.SLBinaryNode; +import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.nodes.SLTypes; import com.oracle.truffle.sl.runtime.SLBigNumber; @@ -127,4 +129,12 @@ protected boolean isString(Object a, Object b) { protected Object typeError(Object left, Object right) { throw SLException.typeError(this, left, right); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLAddNode)) return false; + SLAddNode thatAdd = (SLAddNode) that; + return getLeftNode().isEqualNode(thatAdd.getLeftNode()) + && getRightNode().isEqualNode(thatAdd.getRightNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLBigIntegerLiteralNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLBigIntegerLiteralNode.java index 29ae124343a7..2327b33a1290 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLBigIntegerLiteralNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLBigIntegerLiteralNode.java @@ -45,6 +45,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLBigNumber; /** @@ -64,4 +65,10 @@ public SLBigIntegerLiteralNode(BigInteger value) { public SLBigNumber executeGeneric(VirtualFrame frame) { return value; } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLBigIntegerLiteralNode)) return false; + return value.equals(((SLBigIntegerLiteralNode) that).value); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java index 7ef3936b39c6..3c6f55a00ae0 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java @@ -46,6 +46,8 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLException; import com.oracle.truffle.sl.nodes.SLBinaryNode; +import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLBigNumber; /** @@ -78,4 +80,12 @@ protected SLBigNumber div(SLBigNumber left, SLBigNumber right) { protected Object typeError(Object left, Object right) { throw SLException.typeError(this, left, right); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLDivNode)) return false; + SLDivNode thatAdd = (SLDivNode) that; + return getLeftNode().isEqualNode(thatAdd.getLeftNode()) + && getRightNode().isEqualNode(thatAdd.getRightNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java index 9962099af7ca..3161243da4b6 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java @@ -49,6 +49,8 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.nodes.SLBinaryNode; +import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLBigNumber; import com.oracle.truffle.sl.runtime.SLFunction; import com.oracle.truffle.sl.runtime.SLNull; @@ -152,4 +154,11 @@ public boolean doGeneric(Object left, Object right, } } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLEqualNode)) return false; + SLEqualNode thatAdd = (SLEqualNode) that; + return getLeftNode().isEqualNode(thatAdd.getLeftNode()) + && getRightNode().isEqualNode(thatAdd.getRightNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java index f13e4f39012e..f7e23b3ea5ca 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java @@ -50,10 +50,13 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLLanguage; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLContext; import com.oracle.truffle.sl.runtime.SLFunction; import com.oracle.truffle.sl.runtime.SLFunctionRegistry; +import java.util.Objects; + /** * Constant literal for a {@link SLFunction function} value, created when a function name occurs as * a literal in SL source code. Note that function redefinition can change the {@link CallTarget @@ -129,4 +132,10 @@ public SLFunction executeGeneric(VirtualFrame frame) { return function; } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLFunctionLiteralNode)) return false; + SLFunctionLiteralNode thatFunc = (SLFunctionLiteralNode) that; + return Objects.equals(functionName, thatFunc.functionName); // TODO + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLInvokeNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLInvokeNode.java index 57d58cd32af3..c88277b261f6 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLInvokeNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLInvokeNode.java @@ -51,6 +51,7 @@ import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLFunction; import com.oracle.truffle.sl.runtime.SLUndefinedNameException; @@ -109,4 +110,15 @@ public boolean hasTag(Class tag) { return super.hasTag(tag); } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLInvokeNode)) return false; + SLInvokeNode thatInvoke = (SLInvokeNode) that; + if (!functionNode.isEqualNode(thatInvoke.functionNode) || argumentNodes.length != thatInvoke.argumentNodes.length) return false; + for (int i = 0; i < argumentNodes.length; i++) { + if (!argumentNodes[i].isEqualNode(thatInvoke.argumentNodes[i])) return false; + } + + return true; + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessOrEqualNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessOrEqualNode.java index b0cf8e9f8350..a9f52be8d545 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessOrEqualNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessOrEqualNode.java @@ -46,6 +46,8 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLException; import com.oracle.truffle.sl.nodes.SLBinaryNode; +import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLBigNumber; /** @@ -69,4 +71,12 @@ protected boolean lessOrEqual(SLBigNumber left, SLBigNumber right) { protected Object typeError(Object left, Object right) { throw SLException.typeError(this, left, right); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLLessOrEqualNode)) return false; + SLLessOrEqualNode thatAdd = (SLLessOrEqualNode) that; + return getLeftNode().isEqualNode(thatAdd.getLeftNode()) + && getRightNode().isEqualNode(thatAdd.getRightNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessThanNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessThanNode.java index 60138df8463f..1c4ec984c3a9 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessThanNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessThanNode.java @@ -46,6 +46,8 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLException; import com.oracle.truffle.sl.nodes.SLBinaryNode; +import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLBigNumber; /** @@ -71,4 +73,11 @@ protected Object typeError(Object left, Object right) { throw SLException.typeError(this, left, right); } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLLessThanNode)) return false; + SLLessThanNode thatAdd = (SLLessThanNode) that; + return getLeftNode().isEqualNode(thatAdd.getRightNode()) + && getRightNode().isEqualNode(thatAdd.getRightNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalAndNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalAndNode.java index 83e6632828f2..c065b576c7b5 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalAndNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalAndNode.java @@ -42,6 +42,7 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Logical conjunction node with short circuit evaluation. @@ -71,4 +72,11 @@ protected boolean execute(boolean left, boolean right) { return left && right; } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLLogicalAndNode)) return false; + SLLogicalAndNode thatAdd = (SLLogicalAndNode) that; + return left.isEqualNode(thatAdd.left) + && right.isEqualNode(thatAdd.right); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalNotNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalNotNode.java index 0eff7f861925..df70cefa99d9 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalNotNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalNotNode.java @@ -46,6 +46,7 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLException; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Example of a simple unary node that uses type specialization. See {@link SLAddNode} for @@ -55,6 +56,8 @@ @NodeInfo(shortName = "!") public abstract class SLLogicalNotNode extends SLExpressionNode { + protected abstract SLExpressionNode getValueNode(); + @Specialization protected boolean doBoolean(boolean value) { return !value; @@ -65,4 +68,9 @@ protected Object typeError(Object value) { throw SLException.typeError(this, value); } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLLogicalNotNode)) return false; + return getValueNode().isEqualNode(((SLLogicalNotNode) that).getValueNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalOrNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalOrNode.java index 1d27083207ad..d0b1b19a4803 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalOrNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalOrNode.java @@ -42,6 +42,7 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Logical disjunction node with short circuit evaluation. @@ -63,4 +64,11 @@ protected boolean execute(boolean left, boolean right) { return left || right; } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLLogicalOrNode)) return false; + SLLogicalOrNode thatAdd = (SLLogicalOrNode) that; + return left.isEqualNode(thatAdd.left) + && right.isEqualNode(thatAdd.right); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLongLiteralNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLongLiteralNode.java index 1374851f4c3f..f7cf82b2b971 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLongLiteralNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLongLiteralNode.java @@ -44,6 +44,7 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.nodes.UnexpectedResultException; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Constant literal for a primitive {@code long} value. The unboxed value can be returned when the @@ -68,4 +69,10 @@ public long executeLong(VirtualFrame frame) throws UnexpectedResultException { public Object executeGeneric(VirtualFrame frame) { return value; } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLLongLiteralNode)) return false; + return value == ((SLLongLiteralNode) that).value; + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLMulNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLMulNode.java index 024ca67b3d41..8f24f56748a0 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLMulNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLMulNode.java @@ -46,6 +46,8 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLException; import com.oracle.truffle.sl.nodes.SLBinaryNode; +import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLBigNumber; /** @@ -70,4 +72,12 @@ protected Object typeError(Object left, Object right) { throw SLException.typeError(this, left, right); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLMulNode)) return false; + SLMulNode thatAdd = (SLMulNode) that; + return getLeftNode().isEqualNode(thatAdd.getLeftNode()) + && getRightNode().isEqualNode(thatAdd.getRightNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLParenExpressionNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLParenExpressionNode.java index 420843168751..8c517f61dcc3 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLParenExpressionNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLParenExpressionNode.java @@ -44,6 +44,7 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.nodes.UnexpectedResultException; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * A {@link SLExpressionNode} that represents a parenthesized expression; it simply returns the @@ -74,4 +75,10 @@ public long executeLong(VirtualFrame frame) throws UnexpectedResultException { public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException { return expression.executeBoolean(frame); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLParenExpressionNode)) return false; + return expression.isEqualNode(((SLParenExpressionNode) that).expression); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLReadPropertyNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLReadPropertyNode.java index 1a9d8d000d61..a5561f3e5d0f 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLReadPropertyNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLReadPropertyNode.java @@ -50,6 +50,7 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.nodes.util.SLToMemberNode; import com.oracle.truffle.sl.runtime.SLUndefinedNameException; @@ -68,6 +69,9 @@ public abstract class SLReadPropertyNode extends SLExpressionNode { static final int LIBRARY_LIMIT = 3; + protected abstract SLExpressionNode getReceiverNode(); + protected abstract SLExpressionNode getNameNode(); + @Specialization(guards = "arrays.hasArrayElements(receiver)", limit = "LIBRARY_LIMIT") protected Object readArray(Object receiver, Object index, @CachedLibrary("receiver") InteropLibrary arrays, @@ -92,4 +96,11 @@ protected Object readObject(Object receiver, Object name, } } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLReadPropertyNode)) return false; + final SLReadPropertyNode thatRP = (SLReadPropertyNode) that; + return getReceiverNode().isEqualNode(thatRP.getReceiverNode()) + && getNameNode().isEqualNode(thatRP.getNameNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLShortCircuitNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLShortCircuitNode.java index a8310a2c4221..bfdc77938103 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLShortCircuitNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLShortCircuitNode.java @@ -53,8 +53,8 @@ */ public abstract class SLShortCircuitNode extends SLExpressionNode { - @Child private SLExpressionNode left; - @Child private SLExpressionNode right; + @Child protected SLExpressionNode left; + @Child protected SLExpressionNode right; /** * Short circuits might be used just like a conditional statement it makes sense to profile the diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLStringLiteralNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLStringLiteralNode.java index 8a9eaf217fa3..5019943f699a 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLStringLiteralNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLStringLiteralNode.java @@ -43,6 +43,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; /** * Constant literal for a String value. @@ -60,4 +61,10 @@ public SLStringLiteralNode(String value) { public String executeGeneric(VirtualFrame frame) { return value; } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLStringLiteralNode)) return false; + return value.equals(((SLStringLiteralNode) that).value); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLSubNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLSubNode.java index b21bb1d7496a..ffd6da5bcba2 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLSubNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLSubNode.java @@ -46,6 +46,7 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.sl.SLException; import com.oracle.truffle.sl.nodes.SLBinaryNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.runtime.SLBigNumber; /** @@ -70,4 +71,11 @@ protected Object typeError(Object left, Object right) { throw SLException.typeError(this, left, right); } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLSubNode)) return false; + final SLSubNode thatSub = (SLSubNode) that; + return getLeftNode().isEqualNode(thatSub.getLeftNode()) + && getRightNode().isEqualNode(thatSub.getRightNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLWritePropertyNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLWritePropertyNode.java index af87a3a39737..14f77fce89c1 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLWritePropertyNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLWritePropertyNode.java @@ -41,6 +41,7 @@ package com.oracle.truffle.sl.nodes.expression; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.CachedContext; import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.InteropLibrary; @@ -50,8 +51,12 @@ import com.oracle.truffle.api.interop.UnsupportedTypeException; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.sl.SLLanguage; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.nodes.util.SLToMemberNode; +import com.oracle.truffle.sl.parser.SimpleLanguageParser; +import com.oracle.truffle.sl.runtime.SLContext; import com.oracle.truffle.sl.runtime.SLUndefinedNameException; /** @@ -72,12 +77,20 @@ public abstract class SLWritePropertyNode extends SLExpressionNode { static final int LIBRARY_LIMIT = 3; + protected abstract SLExpressionNode getReceiverNode(); + protected abstract SLExpressionNode getNameNode(); + protected abstract SLExpressionNode getValueNode(); + @Specialization(guards = "arrays.hasArrayElements(receiver)", limit = "LIBRARY_LIMIT") protected Object writeArray(Object receiver, Object index, Object value, - @CachedLibrary("receiver") InteropLibrary arrays, - @CachedLibrary("index") InteropLibrary numbers) { + @CachedLibrary("receiver") InteropLibrary arrays, + @CachedLibrary("index") InteropLibrary numbers, + @CachedContext(SLLanguage.class) SLContext context) { + System.out.println(getNameNode().toString()); try { - arrays.writeArrayElement(receiver, numbers.asLong(index), value); + final long i = numbers.asLong(index); + arrays.writeArrayElement(receiver, i, value); + context.getObjectTracker().notifyAssignment(receiver, i, value); } catch (UnsupportedMessageException | UnsupportedTypeException | InvalidArrayIndexException e) { // read was not successful. In SL we only have basic support for errors. throw SLUndefinedNameException.undefinedProperty(this, index); @@ -88,9 +101,12 @@ protected Object writeArray(Object receiver, Object index, Object value, @Specialization(limit = "LIBRARY_LIMIT") protected Object writeObject(Object receiver, Object name, Object value, @CachedLibrary("receiver") InteropLibrary objectLibrary, - @Cached SLToMemberNode asMember) { + @Cached SLToMemberNode asMember, + @CachedContext(SLLanguage.class) SLContext context) { try { - objectLibrary.writeMember(receiver, asMember.execute(name), value); + final String id = asMember.execute(name); + objectLibrary.writeMember(receiver, id, value); + context.getObjectTracker().notifyAssignment(receiver, id, value); } catch (UnsupportedMessageException | UnknownIdentifierException | UnsupportedTypeException e) { // write was not successful. In SL we only have basic support for errors. throw SLUndefinedNameException.undefinedProperty(this, name); @@ -98,4 +114,12 @@ protected Object writeObject(Object receiver, Object name, Object value, return value; } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLWritePropertyNode)) return false; + final SLWritePropertyNode thatWP = (SLWritePropertyNode) that; + return getReceiverNode().isEqualNode(thatWP.getReceiverNode()) + && getNameNode().isEqualNode(thatWP.getNameNode()) + && getValueNode().isEqualNode(thatWP.getValueNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java index 3f5e28e4ad79..5a5ade29342d 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java @@ -43,6 +43,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.parser.SLNodeFactory; import com.oracle.truffle.sl.runtime.SLNull; @@ -80,4 +81,10 @@ public Object executeGeneric(VirtualFrame frame) { return SLNull.SINGLETON; } } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLReadArgumentNode)) return false; + return index == ((SLReadArgumentNode) that).index; + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java index b825e10dc448..2e2bf83d7cc1 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java @@ -49,6 +49,7 @@ import com.oracle.truffle.api.instrumentation.StandardTags.ReadVariableTag; import com.oracle.truffle.api.instrumentation.Tag; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.nodes.interop.NodeObjectDescriptor; /** @@ -113,4 +114,10 @@ public boolean hasTag(Class tag) { public Object getNodeObject() { return NodeObjectDescriptor.readVariable(getSlot().getIdentifier().toString()); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLReadLocalVariableNode)) return false; + return getSlot().getIdentifier().equals(((SLReadLocalVariableNode) that).getSlot().getIdentifier()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java index a8251aa178e9..089b3d0d7923 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java @@ -40,6 +40,7 @@ */ package com.oracle.truffle.sl.nodes.local; +import com.oracle.truffle.api.dsl.CachedContext; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.NodeField; @@ -51,8 +52,11 @@ import com.oracle.truffle.api.instrumentation.Tag; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.sl.SLLanguage; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.nodes.interop.NodeObjectDescriptor; +import com.oracle.truffle.sl.runtime.SLContext; /** * Node to write a local variable to a function's {@link VirtualFrame frame}. The Truffle frame API @@ -84,20 +88,22 @@ public abstract class SLWriteLocalVariableNode extends SLExpressionNode { * therefore a Truffle DSL {@link #isLongOrIllegal(VirtualFrame) custom guard} is specified. */ @Specialization(guards = "isLongOrIllegal(frame)") - protected long writeLong(VirtualFrame frame, long value) { + protected long writeLong(VirtualFrame frame, long value, @CachedContext(SLLanguage.class) SLContext context) { /* Initialize type on first write of the local variable. No-op if kind is already Long. */ frame.getFrameDescriptor().setFrameSlotKind(getSlot(), FrameSlotKind.Long); frame.setLong(getSlot(), value); + context.getStackTracker().notifyLongSet(getSlot(), value); return value; } @Specialization(guards = "isBooleanOrIllegal(frame)") - protected boolean writeBoolean(VirtualFrame frame, boolean value) { + protected boolean writeBoolean(VirtualFrame frame, boolean value, @CachedContext(SLLanguage.class) SLContext context) { /* Initialize type on first write of the local variable. No-op if kind is already Long. */ frame.getFrameDescriptor().setFrameSlotKind(getSlot(), FrameSlotKind.Boolean); frame.setBoolean(getSlot(), value); + context.getStackTracker().notifyBooleanSet(getSlot(), value); return value; } @@ -112,7 +118,7 @@ protected boolean writeBoolean(VirtualFrame frame, boolean value) { * node will never be re-specialized. */ @Specialization(replaces = {"writeLong", "writeBoolean"}) - protected Object write(VirtualFrame frame, Object value) { + protected Object write(VirtualFrame frame, Object value, @CachedContext(SLLanguage.class) SLContext context) { /* * Regardless of the type before, the new and final type of the local variable is Object. * Changing the slot kind also discards compiled code, because the variable type is @@ -123,6 +129,7 @@ protected Object write(VirtualFrame frame, Object value) { frame.getFrameDescriptor().setFrameSlotKind(getSlot(), FrameSlotKind.Object); frame.setObject(getSlot(), value); + context.getStackTracker().notifyObjectSet(getSlot(), value); return value; } @@ -168,4 +175,10 @@ public Object getNodeObject() { } return NodeObjectDescriptor.writeVariable(getSlot().getIdentifier().toString(), nameSourceSection); } + + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLWriteLocalVariableNode)) return false; + return getNameNode().isEqualNode(((SLWriteLocalVariableNode) that).getNameNode()); + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/util/SLUnboxNode.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/util/SLUnboxNode.java index d2f7fde4d743..e1be2878521b 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/util/SLUnboxNode.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/util/SLUnboxNode.java @@ -49,6 +49,7 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.sl.nodes.SLExpressionNode; +import com.oracle.truffle.sl.nodes.SLStatementNode; import com.oracle.truffle.sl.nodes.SLTypes; import com.oracle.truffle.sl.runtime.SLBigNumber; import com.oracle.truffle.sl.runtime.SLFunction; @@ -113,4 +114,9 @@ public static Object fromForeign(Object value, @CachedLibrary("value") InteropLi } } + @Override + public boolean isEqualNode(SLStatementNode that) { + if (!(that instanceof SLUnboxNode)) return false; + return true; //TODO + } } diff --git a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java index 771ad3769edb..73d888e4e1aa 100644 --- a/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java +++ b/truffle/src/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java @@ -54,6 +54,8 @@ import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.instrumentation.AllocationReporter; +import com.oracle.truffle.api.instrumentation.ObjectTracker; +import com.oracle.truffle.api.instrumentation.StackTracker; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.sl.SLLanguage; @@ -93,6 +95,9 @@ public final class SLContext { private final PrintWriter output; private final SLFunctionRegistry functionRegistry; private final AllocationReporter allocationReporter; + private final ObjectTracker objectTracker; + + private final StackTracker stackTracker; public SLContext(SLLanguage language, TruffleLanguage.Env env, List> externalBuiltins) { this.env = env; @@ -101,6 +106,8 @@ public SLContext(SLLanguage language, TruffleLanguage.Env env, List builtin : externalBuiltins) { installBuiltin(builtin); @@ -218,4 +225,11 @@ public static SLContext getCurrent() { return SLLanguage.getCurrentContext(); } + public ObjectTracker getObjectTracker() { + return objectTracker; + } + + public StackTracker getStackTracker() { + return stackTracker; + } } From ec609caeb593162ff35b715c699cacd23f9d0b84 Mon Sep 17 00:00:00 2001 From: Shusuke Takahashi Date: Mon, 8 Aug 2022 01:51:11 +0900 Subject: [PATCH 8/8] Add shell runs sl --- truffle/sl.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 truffle/sl.sh diff --git a/truffle/sl.sh b/truffle/sl.sh new file mode 100644 index 000000000000..085d46732f13 --- /dev/null +++ b/truffle/sl.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +/usr/lib64/openjdk-11/bin/java --add-modules=org.graalvm.truffle --module-path=/home/pois/Programs/graal/graal/truffle/mxbuild/dists/jdk11/truffle-api.jar:$GRAAL_PRJ_HOME/graal/sdk/mxbuild/linux-amd64/GRAALVM_591BD358E0_JAVA11/graalvm-591bd358e0-java11-21.0.0-dev/lib/:$GRAAL_PRJ_HOME/graal/sdk/mxbuild/dists/jdk11/: -cp /home/pois/.mx/cache/ANTLR4_e27d8ab4f984f9d186f54da984a6ab -cp /home/pois/Programs/graal/graal/sdk/mxbuild/dists/jdk11/graal-sdk.jar -cp $GRAAL_PRJ_HOME/graal/truffle/mxbuild/src:/home/pois/Programs/graal/graal/truffle/mxbuild/src/com.oracle.truffle.sl/bin:/home/pois/Programs/graal/graal/truffle/mxbuild/src/com.oracle.truffle.sl.launcher/bin:/home/pois/.mx/cache/ANTLR4_e27d8ab4f984f9d186f54da984a6ab1cccac755e/antlr4.jar com.oracle.truffle.sl.launcher.SLMain