From dff78441a02a1e4648fe58058a7b799c41fb63d3 Mon Sep 17 00:00:00 2001 From: Martin Entlicher <martin.entlicher@oracle.com> Date: Thu, 26 Oct 2017 16:46:57 +0200 Subject: [PATCH] [GR-6010] Use the new Scope class after metadata deprecation, provide global scope. --- .../r/engine/TruffleRLanguageImpl.java | 23 ++-- .../oracle/truffle/r/runtime/env/RScope.java | 110 ++++++++++-------- .../truffle/r/test/tck/FastRDebugTest.java | 23 +++- mx.fastr/suite.py | 2 +- 4 files changed, 89 insertions(+), 69 deletions(-) diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguageImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguageImpl.java index 8fb818136f..6efb2f21fc 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguageImpl.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguageImpl.java @@ -26,18 +26,17 @@ import java.util.HashMap; import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.Scope; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.instrumentation.Instrumenter; import com.oracle.truffle.api.instrumentation.ProvidedTags; import com.oracle.truffle.api.instrumentation.StandardTags; -import com.oracle.truffle.api.metadata.ScopeProvider; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.engine.interop.RForeignAccessFactoryImpl; import com.oracle.truffle.r.nodes.RASTBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinPackages; -import com.oracle.truffle.r.nodes.function.PromiseHelperNode; import com.oracle.truffle.r.nodes.instrumentation.RSyntaxTags; import com.oracle.truffle.r.runtime.ExitException; import com.oracle.truffle.r.runtime.FastROptions; @@ -60,7 +59,7 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode; @TruffleLanguage.Registration(name = "R", id = "R", version = "3.3.2", mimeType = {RRuntime.R_APP_MIME, RRuntime.R_TEXT_MIME}, interactive = true) @ProvidedTags({StandardTags.CallTag.class, StandardTags.StatementTag.class, StandardTags.RootTag.class, RSyntaxTags.LoopTag.class}) -public final class TruffleRLanguageImpl extends TruffleRLanguage implements ScopeProvider<RContext> { +public final class TruffleRLanguageImpl extends TruffleRLanguage { private final HashMap<String, RFunction> builtinFunctionCache = new HashMap<>(); @@ -201,15 +200,6 @@ public final class TruffleRLanguageImpl extends TruffleRLanguage implements Scop private static final R2Foreign r2foreign = R2ForeignNodeGen.create(); - @Override - protected Object lookupSymbol(RContext context, String symbolName) { - Object value = context.stateREnvironment.getGlobalEnv().get(symbolName); - if (value instanceof RPromise) { - value = PromiseHelperNode.evaluateSlowPath((RPromise) value); - } - return value != null ? r2foreign.execute(value) : null; - } - @Override protected Object getLanguageGlobal(RContext context) { // TODO: what's the meaning of "language global" for R? @@ -225,7 +215,12 @@ public final class TruffleRLanguageImpl extends TruffleRLanguage implements Scop } @Override - public AbstractScope findScope(RContext langContext, Node node, Frame frame) { - return RScope.createScope(node, frame); + public Iterable<Scope> findLocalScopes(RContext langContext, Node node, Frame frame) { + return RScope.createLocalScopes(langContext, node, frame); + } + + @Override + protected Iterable<Scope> findTopScopes(RContext langContext) { + return RScope.createTopScopes(langContext); } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/RScope.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/RScope.java index b8cb17148d..cb2d3141e1 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/RScope.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/RScope.java @@ -22,7 +22,12 @@ */ package com.oracle.truffle.r.runtime.env; +import java.util.Collections; +import java.util.Iterator; +import java.util.NoSuchElementException; + import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.Scope; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.interop.ForeignAccess; @@ -35,7 +40,6 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.api.metadata.ScopeProvider.AbstractScope; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RArguments; @@ -52,7 +56,7 @@ import com.oracle.truffle.r.runtime.env.frame.REnvTruffleFrameAccess; * Represents a variable scope for external tools like a debugger.<br> * This is basically a view on R environments. */ -public final class RScope extends AbstractScope { +public final class RScope { private final Node current; private REnvironment env; @@ -70,7 +74,6 @@ public final class RScope extends AbstractScope { this.env = env; } - @Override protected String getName() { // just to be sure if (env == REnvironment.emptyEnv()) { @@ -88,13 +91,11 @@ public final class RScope extends AbstractScope { } } - @Override protected Node getNode() { return current; } - @Override - protected Object getVariables(Frame frame) { + protected Object getVariables() { return new EnvVariablesObject(env, false); } @@ -105,25 +106,72 @@ public final class RScope extends AbstractScope { return null; } - @Override - protected Object getArguments(Frame frame) { + protected Object getArguments() { return new EnvVariablesObject(env, true); } - @Override - protected AbstractScope findParent() { + protected RScope findParent() { if (env == REnvironment.emptyEnv() || env.getParent() == REnvironment.emptyEnv()) { return null; } return new RScope(env.getParent()); } - public static AbstractScope createScope(Node node, Frame frame) { + public static Iterable<Scope> createLocalScopes(RContext context, Node node, Frame frame) { REnvironment env = getEnv(frame); + if (env == context.stateREnvironment.getGlobalEnv()) { + return Collections.emptySet(); + } if (env != null && env != REnvironment.emptyEnv()) { - return new RScope(node.getRootNode(), env); + RScope scope = new RScope(node.getRootNode(), env); + return createScopes(scope, context.stateREnvironment.getGlobalEnv()); } - return new GenericScope(node, frame.materialize()); + MaterializedFrame mFrame = frame.materialize(); + String name = node.getRootNode().getName(); + if (name == null) { + name = "local"; + } + return Collections.singleton(Scope.newBuilder(name, new GenericVariablesObject(mFrame, false)).node(node).arguments(new GenericVariablesObject(mFrame, true)).build()); + } + + public static Iterable<Scope> createTopScopes(RContext context) { + REnvironment env = context.stateREnvironment.getGlobalEnv(); + RScope scope = new RScope(env); + return createScopes(scope, null); + } + + private static Iterable<Scope> createScopes(RScope scope, REnvironment toEnv) { + return new Iterable<Scope>() { + @Override + public Iterator<Scope> iterator() { + return new Iterator<Scope>() { + private RScope previousScope; + private RScope nextScope = scope; + + @Override + public boolean hasNext() { + if (nextScope == null) { + nextScope = previousScope.findParent(); + if (nextScope != null && nextScope.env == toEnv) { + nextScope = null; + } + } + return nextScope != null; + } + + @Override + public Scope next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + Scope vscope = Scope.newBuilder(nextScope.getName(), nextScope.getVariables()).node(nextScope.getNode()).arguments(nextScope.getArguments()).build(); + previousScope = nextScope; + nextScope = null; + return vscope; + } + }; + } + }; } /** @@ -138,42 +186,6 @@ public final class RScope extends AbstractScope { return obj; } - private static final class GenericScope extends AbstractScope { - - private final MaterializedFrame mFrame; - private final Node node; - - protected GenericScope(Node node, MaterializedFrame frame) { - this.node = node; - this.mFrame = frame; - } - - @Override - protected String getName() { - return node.getRootNode().getName(); - } - - @Override - protected Node getNode() { - return node; - } - - @Override - protected Object getVariables(Frame frame) { - return new GenericVariablesObject(mFrame, false); - } - - @Override - protected Object getArguments(Frame frame) { - return new GenericVariablesObject(mFrame, true); - } - - @Override - protected AbstractScope findParent() { - return null; - } - } - abstract static class VariablesObject implements TruffleObject { private final REnvFrameAccess frameAccess; diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java index b1fbb4910b..71fe0d2b1b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java @@ -582,6 +582,9 @@ public class FastRDebugTest { final DebugStackFrame frame = suspendedEvent.getTopStackFrame(); DebugScope scope = frame.getScope(); + if (scope == null) { + scope = suspendedEvent.getSession().getTopScope("application/x-r"); + } Set<String> actualIdentifiers = new HashSet<>(); scope.getArguments().forEach((x) -> actualIdentifiers.add(x.getName())); @@ -627,11 +630,21 @@ public class FastRDebugTest { Object expectedValue = expectedFrame[i + 1]; String expectedValueStr = (expectedValue != null) ? expectedValue.toString() : null; DebugScope scope = frame.getScope(); - DebugValue value; - do { - value = scope.getDeclaredValue(expectedIdentifier); - scope = scope.getParent(); - } while (includeAncestors && value == null && scope != null && !REnvironment.baseEnv().getName().equals(scope.getName())); + DebugValue value = null; + if (scope != null) { + do { + value = scope.getDeclaredValue(expectedIdentifier); + scope = scope.getParent(); + } while (includeAncestors && value == null && scope != null && !REnvironment.baseEnv().getName().equals(scope.getName())); + } + if (value == null) { + // Ask the top scope: + scope = suspendedEvent.getSession().getTopScope("application/x-r"); + do { + value = scope.getDeclaredValue(expectedIdentifier); + scope = scope.getParent(); + } while (includeAncestors && value == null && scope != null && !REnvironment.baseEnv().getName().equals(scope.getName())); + } assertNotNull("identifier \"" + expectedIdentifier + "\" not found", value); String valueStr = value.as(String.class); assertEquals(expectedValueStr, valueStr); diff --git a/mx.fastr/suite.py b/mx.fastr/suite.py index bfb8500be9..fcbca55fbf 100644 --- a/mx.fastr/suite.py +++ b/mx.fastr/suite.py @@ -29,7 +29,7 @@ suite = { { "name" : "truffle", "subdir" : True, - "version" : "f7eb693d02cc090cbaab6ec9dfce0b5d9d22b716", + "version" : "d1bb9076f1fa6af71c60be140f980794596a75b4", "urls" : [ {"url" : "https://github.com/graalvm/graal", "kind" : "git"}, {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"}, -- GitLab