From 89e60347546e9b88e1bb7efed50d954c86a409d5 Mon Sep 17 00:00:00 2001
From: Julien Lopez <julien.lopez@lri.fr>
Date: Tue, 20 Feb 2018 14:58:49 +0100
Subject: [PATCH] Use existing engine in QIRInterface and add test on side
 effects

---
 .../truffle/r/launcher/RscriptCommand.java      |  3 +++
 .../r/nodes/qirinterface/QIRInterface.java      | 14 +++-----------
 .../tests/pgsql/QuerySideEffect3.R              | 17 +++++++++++++++++
 .../tests/pgsql/QuerySideEffect3.out            | 12 ++++++++++++
 4 files changed, 35 insertions(+), 11 deletions(-)
 create mode 100644 com.oracle.truffle.r.test/tests/pgsql/QuerySideEffect3.R
 create mode 100644 com.oracle.truffle.r.test/tests/pgsql/QuerySideEffect3.out

diff --git a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RscriptCommand.java b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RscriptCommand.java
index c274a24976..7ed68516b4 100644
--- a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RscriptCommand.java
+++ b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RscriptCommand.java
@@ -103,6 +103,8 @@ public class RscriptCommand {
         throw RCommand.fatal("should not reach here");
     }
 
+    public static Context currentContext = null;
+
     public static int doMain(String[] args, String[] env, InputStream inStream, OutputStream outStream, OutputStream errStream) {
         assert env == null : "re-enble environment variables";
 
@@ -130,6 +132,7 @@ public class RscriptCommand {
 
         ConsoleHandler consoleHandler = RCommand.createConsoleHandler(options, false, inStream, outStream);
         try (Context context = Context.newBuilder().options(polyglotOptions).arguments("R", arguments).in(consoleHandler.createInputStream()).out(outStream).err(errStream).build()) {
+            currentContext = context;
             consoleHandler.setContext(context);
             return RCommand.readEvalPrint(context, consoleHandler);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java
index 10a68241a3..0600a0d7f0 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java
@@ -29,15 +29,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-import com.oracle.truffle.api.TruffleLanguage.Env;
 import com.oracle.truffle.api.frame.Frame;
 import com.oracle.truffle.api.frame.FrameDescriptor;
 import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.api.vm.EngineTruffleObject;
-import com.oracle.truffle.api.vm.PolyglotEngine;
-import com.oracle.truffle.api.vm.PolyglotEngine.Value;
+import com.oracle.truffle.r.launcher.RscriptCommand;
 import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode;
 import com.oracle.truffle.r.nodes.function.FunctionExpressionNode;
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -243,14 +241,8 @@ public final class QIRInterface {
     }
 
     static final QIRNode execute(final String program) {
-        final Env env = RContext.getInstance().getEnv();
-        final PolyglotEngine vm = PolyglotEngine.newBuilder().config(RRuntime.R_APP_MIME, "REngine", null).setIn(env.in()).setOut(env.out()).build();
-        final Source source = Source.newBuilder(program).name("mySrc").mimeType(RRuntime.R_APP_MIME).build();
-        final Value v = vm.eval(source);
-
-        if (v == null)
-            throw new RuntimeException("No function main() defined in R source file." + source.getCharacters().toString());
-        return RToQIRType(v.getSourceLocation(), v.get());
+        // TODO: getReceiver does not exist in real Graal
+        return RToQIRType(null, RscriptCommand.currentContext.eval("R", program).getReceiver());
     }
 
     static final QIRTruffleNode apply(final QIRTruffleNode fun, final List<QIRNode> args) {
diff --git a/com.oracle.truffle.r.test/tests/pgsql/QuerySideEffect3.R b/com.oracle.truffle.r.test/tests/pgsql/QuerySideEffect3.R
new file mode 100644
index 0000000000..b613872c7e
--- /dev/null
+++ b/com.oracle.truffle.r.test/tests/pgsql/QuerySideEffect3.R
@@ -0,0 +1,17 @@
+emp = new.tableRef("emp", "PostgreSQL", "postgre.config", "public")
+minsalary = 2500.0
+q = query.select(function (x) {
+             res = new.env()
+             res$empno = x$empno
+             res$ename = x$ename
+	     print(paste("salary:", x$sal))
+             res$salary = (function (dol){
+               a = dol * 89.0 / 100.0
+               while (a > 1000.0) a = a * 89.0 / 100.0
+               a
+             })(x$sal)
+             res },
+    query.where(function (x) x$sal >= minsalary,
+    query.from(emp)))
+results = query.force(q)
+print(results)
diff --git a/com.oracle.truffle.r.test/tests/pgsql/QuerySideEffect3.out b/com.oracle.truffle.r.test/tests/pgsql/QuerySideEffect3.out
new file mode 100644
index 0000000000..a4b5afba4b
--- /dev/null
+++ b/com.oracle.truffle.r.test/tests/pgsql/QuerySideEffect3.out
@@ -0,0 +1,12 @@
+[1] "salary: 2500"
+[1] "salary: 5220"
+[1] "salary: 3500"
+[1] "salary: 4235"
+[1] "salary: 5000"
+  ename empno   salary
+1 SMITH     1 984.1472
+2  WARD     3 908.9094
+3 JONES     4 971.3106
+4 SCOTT     8 930.9439
+5 ADAMS    11 978.2055
+
-- 
GitLab