From 87e2be9b7dc4a79460b44f11aa2ae3fb6f3f0ca9 Mon Sep 17 00:00:00 2001 From: Julien Lopez <julien.lopez@lri.fr> Date: Mon, 26 Jun 2017 11:41:10 +0200 Subject: [PATCH] FastR is now embeddable in PostgreSQL --- .../com/oracle/truffle/r/engine/REngine.java | 34 ++++++++++++++++--- .../r/nodes/builtin/RBuiltinPackage.java | 2 +- .../truffle/r/nodes/RSyntaxNodeVisitor.java | 4 +++ .../qirinterface/QIRTranslateVisitor.java | 5 +++ .../truffle/r/nodes/query/RQueryVisitor.java | 5 +++ .../truffle/r/runtime/context/RContext.java | 18 ++++++++-- 6 files changed, 60 insertions(+), 8 deletions(-) diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index ef4cb07f62..248c2488ea 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -51,6 +51,8 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.api.vm.PolyglotEngine; +import com.oracle.truffle.api.vm.PolyglotEngine.Value; import com.oracle.truffle.r.library.graphics.RGraphics; import com.oracle.truffle.r.nodes.RASTBuilder; import com.oracle.truffle.r.nodes.RASTUtils; @@ -327,20 +329,26 @@ final class REngine implements Engine, Engine.Timings { } public static final RValue executeR(final String program) throws IOException { - return new RValue( - (Serializable) RContext.getEngine().parseAndEval(Source.newBuilder(program).name("RBuilder").mimeType(RRuntime.R_APP_MIME).build(), REnvironment.baseEnv().getFrame(), false)); + RContext.setDeepEmbedded(); + final Value v = PolyglotEngine.newBuilder().config("application/x-r", "REngine", null).build().eval(Source.newBuilder(program).name("RBuilder").mimeType(RRuntime.R_APP_MIME).build()); + final Object res = v.get(); + if (res instanceof Serializable) + return new RValue((Serializable) res); + return new RValue(v.getSourceLocation().getCode()); } public static final RValue executeApply(final RValue fun, final RValue args[]) throws IOException { - final String program = "f = " + fun + "\nf(" + Arrays.stream(args).map(arg -> arg.getValue().toString()).collect(Collectors.joining(", ")) + ")"; - return new RValue( - (Serializable) RContext.getEngine().parseAndEval(Source.newBuilder(program).name("RBuilder").mimeType(RRuntime.R_APP_MIME).build(), REnvironment.baseEnv().getFrame(), false)); + return executeR("f = " + fun.getValue() + "\nf(" + Arrays.stream(args).map(arg -> arg.getValue().toString()).collect(Collectors.joining(", ")) + ")"); } public static final RValue translate(final Integer i) throws IOException { return new RValue(i); } + public static final RValue translate(final Double d) throws IOException { + return new RValue(d); + } + public static final RValue translate(final String s) throws IOException { return new RValue(s); } @@ -349,6 +357,22 @@ final class REngine implements Engine, Engine.Timings { return new RValue(b); } + public static final Integer translateBackToInteger(final RValue v) { + return (Integer) v.getValue(); + } + + public static final Double translateBackToDouble(final RValue v) { + return (Double) v.getValue(); + } + + public static final String translateBackToString(final RValue v) { + return (String) v.getValue(); + } + + public static final Boolean translateBackToBoolean(final RValue v) { + return (Boolean) v.getValue(); + } + private final class PolyglotEngineRootNode extends RootNode { private final List<RSyntaxNode> statements; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackage.java index 980ba240c7..784313d1df 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackage.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackage.java @@ -111,7 +111,7 @@ public abstract class RBuiltinPackage { ArrayList<Source> componentList = new ArrayList<>(); String[] rFileContents = rFilesCache.get(pkgName); if (rFileContents == null) { - rFileContents = ResourceHandlerFactory.getHandler().getRFiles(RBuiltinPackage.class, pkgName); + rFileContents = RContext.isDeepEmbedded() ? new String[]{} : ResourceHandlerFactory.getHandler().getRFiles(RBuiltinPackage.class, pkgName); rFilesCache.put(pkgName, rFileContents); } for (String rFileContent : rFileContents) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RSyntaxNodeVisitor.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RSyntaxNodeVisitor.java index 7ca6bc7cfa..a1e220b242 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RSyntaxNodeVisitor.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RSyntaxNodeVisitor.java @@ -23,6 +23,8 @@ public interface RSyntaxNodeVisitor<T> extends IRSyntaxNodeVisitor<T> { public abstract T visit(final ForNode forNode); + public abstract T visit(final BreakNode b); + public abstract T visit(final BlockNode block); public abstract T visit(final ReadVariableNode var); @@ -69,6 +71,8 @@ public interface RSyntaxNodeVisitor<T> extends IRSyntaxNodeVisitor<T> { return visit((WhileNode) node); if (node instanceof ForNode) return visit((ForNode) node); + if (node instanceof BreakNode) + return visit((BreakNode) node); if (node instanceof BlockNode) return visit((BlockNode) node); if (node instanceof ReadVariableNode) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRTranslateVisitor.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRTranslateVisitor.java index db247b6358..764c96ccaa 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRTranslateVisitor.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRTranslateVisitor.java @@ -61,6 +61,11 @@ public final class QIRTranslateVisitor implements RSyntaxNodeVisitor<QIRNode> { return new QIRTruffleNode(forNode.getSourceSection(), "R", forNode.getSourceSection().getCode()); } + @Override + public final QIRNode visit(final BreakNode breakNode) { + return new QIRTruffleNode(breakNode.getSourceSection(), "R", breakNode.getSourceSection().getCode()); + } + /** * Translation of a sequence of statements. Note: This is also where the STRAD-ASSIGN rules are * handled. diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/query/RQueryVisitor.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/query/RQueryVisitor.java index cfe15724b7..204c6b4c5d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/query/RQueryVisitor.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/query/RQueryVisitor.java @@ -45,6 +45,11 @@ public final class RQueryVisitor implements RSyntaxNodeVisitor<RSyntaxNode> { forNode.getBody().asRSyntaxNode().accept(this).asRNode()); } + @Override + public final RSyntaxNode visit(final BreakNode breakNode) { + return breakNode; + } + @Override public final RSyntaxNode visit(final BlockNode block) { final RNode[] children = block.getSequence(); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java index 9307e6ca2c..b24e381553 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java @@ -416,6 +416,8 @@ public final class RContext extends com.oracle.truffle.api.ExecutionContext impl */ private static boolean embedded; + private static boolean deepEmbedded; + /* * Workarounds to finesse project circularities between runtime/nodes. */ @@ -509,6 +511,15 @@ public final class RContext extends com.oracle.truffle.api.ExecutionContext impl return embedded; } + public static void setDeepEmbedded() { + deepEmbedded = true; + embedded = true; + } + + public static boolean isDeepEmbedded() { + return deepEmbedded; + } + /** * Sets the fields that do not depend on complex initialization. * @@ -597,7 +608,9 @@ public final class RContext extends com.oracle.truffle.api.ExecutionContext impl stateDLL.initialize(this); stateRFFI = RFFIFactory.getInstance().newContextState(); // separate in case initialize calls getStateRFFI()! - stateRFFI.initialize(this); + + if (!deepEmbedded) + stateRFFI.initialize(this); if (!embedded) { doEnvOptionsProfileInitialization(); @@ -607,7 +620,8 @@ public final class RContext extends com.oracle.truffle.api.ExecutionContext impl stateRErrorHandling.initialize(this); stateRConnection.initialize(this); stateStdConnections.initialize(this); - stateRNG.initialize(this); + if (!deepEmbedded) + stateRNG.initialize(this); stateRSerialize.initialize(this); stateLazyDBCache.initialize(this); stateInstrumentation.initialize(this); -- GitLab