From e300081c07e9cae1f44242fe197cdb3681e20a43 Mon Sep 17 00:00:00 2001
From: Julien Lopez <julien.lopez@lri.fr>
Date: Sat, 26 Aug 2017 12:06:40 +0200
Subject: [PATCH] Hack and fix for R execution in databases

---
 .../com/oracle/truffle/r/engine/RExecute.java | 20 +++++++++
 .../truffle/r/engine/RExecuteApply.java       | 12 ++++++
 .../truffle/r/engine/TruffleRLanguage.java    | 42 +++++++++++++++----
 .../r/nodes/builtin/RBuiltinPackage.java      |  2 +-
 .../r/runtime/LazyResourceHandlerFactory.java | 20 ++++++++-
 .../oracle/truffle/r/runtime/REnvVars.java    |  4 +-
 com.oracle.truffle.r.test/hbase-site.xml      | 32 --------------
 7 files changed, 88 insertions(+), 44 deletions(-)
 create mode 100644 com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RExecute.java
 create mode 100644 com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RExecuteApply.java
 delete mode 100644 com.oracle.truffle.r.test/hbase-site.xml

diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RExecute.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RExecute.java
new file mode 100644
index 0000000000..2b0b2a3201
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RExecute.java
@@ -0,0 +1,20 @@
+package com.oracle.truffle.r.engine;
+
+import java.io.Serializable;
+
+import org.apache.hadoop.hive.ql.exec.UDF;
+
+import com.oracle.truffle.api.source.Source;
+import com.oracle.truffle.api.vm.PolyglotEngine;
+import com.oracle.truffle.api.vm.PolyglotEngine.Value;
+import com.oracle.truffle.r.runtime.RRuntime;
+
+public class RExecute extends UDF {
+    public static String evaluate(final String program) {
+        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 res.toString();
+        return v.getSourceLocation().getCode();
+    }
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RExecuteApply.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RExecuteApply.java
new file mode 100644
index 0000000000..a9ed0dbe03
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RExecuteApply.java
@@ -0,0 +1,12 @@
+package com.oracle.truffle.r.engine;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.hadoop.hive.ql.exec.UDF;
+
+public class RExecuteApply extends UDF {
+    public static String evaluate(final String fun, final List<String> args) {
+        return RExecute.evaluate("f = " + fun + ";f(" + args.stream().map(arg -> arg.toString()).collect(Collectors.joining(", ")) + ")");
+    }
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java
index afafa3c17c..58b7dc98bc 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java
@@ -23,9 +23,13 @@
 package com.oracle.truffle.r.engine;
 
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.io.Serializable;
+import java.io.StringWriter;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 import com.oracle.truffle.api.CallTarget;
@@ -261,16 +265,38 @@ public final class TruffleRLanguage extends TruffleLanguage<RContext> implements
         return RScope.createScope(node, frame);
     }
 
-    public static final RValue executeR(final String program) throws IOException {
-        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 Map<String, RValue> valueCache = new HashMap<>();
+    public static PolyglotEngine vm = PolyglotEngine.newBuilder().config("application/x-r", "REngine", null).build();
+
+    public static final RValue executeR(final String program) {
+        RValue res = valueCache.get(program);
+        if (res != null)
+            return res;
+        try {
+            final Value v = vm.eval(Source.newBuilder(program).name("RBuilder").mimeType(RRuntime.R_APP_MIME).build());
+            final Object o = v.get();
+            if (o instanceof Serializable)
+                res = new RValue((Serializable) o);
+            else
+                res = new RValue(v.getSourceLocation().getCode());
+            valueCache.put(program, res);
+            return res;
+        } catch (Exception e) {
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            e.printStackTrace(pw);
+            throw new RuntimeException(sw.toString());
+        }
+    }
+
+    public static final RValue executeApply(final RValue fun, final RValue args[]) {
+        return executeR("f = " + fun.getValue() + "\nf(" + Arrays.stream(args).map(arg -> arg.getValue().toString()).collect(Collectors.joining(", ")) + ")");
     }
 
-    public static final RValue executeApply(final RValue fun, final RValue args[]) throws IOException {
-        return executeR("f = " + fun.getValue() + ";f(" + Arrays.stream(args).map(arg -> arg.getValue().toString()).collect(Collectors.joining(", ")) + ")");
+    public static final String executeApply(final String fun, final String args[]) {
+        return executeR("f = " + fun + "\nf(" +
+                        Arrays.stream(args).map(s -> s.equals("TRUE") ? s : s.equals("FALSE") ? s : s.matches("[A-Za-z_].*") ? "\"" + s + "\"" : s).collect(Collectors.joining(", ")) +
+                        ")").getValue().toString();
     }
 
     public static final RValue translate(final Integer i) throws IOException {
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 784313d1df..980ba240c7 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 = RContext.isDeepEmbedded() ? new String[]{} : ResourceHandlerFactory.getHandler().getRFiles(RBuiltinPackage.class, pkgName);
+            rFileContents = ResourceHandlerFactory.getHandler().getRFiles(RBuiltinPackage.class, pkgName);
             rFilesCache.put(pkgName, rFileContents);
         }
         for (String rFileContent : rFileContents) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/LazyResourceHandlerFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/LazyResourceHandlerFactory.java
index 1befec1946..c4931e0d04 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/LazyResourceHandlerFactory.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/LazyResourceHandlerFactory.java
@@ -24,17 +24,21 @@ package com.oracle.truffle.r.runtime;
 
 import java.io.BufferedReader;
 import java.io.File;
+import java.io.FilePermission;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.security.CodeSource;
+import java.security.Permissions;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
-
 import com.oracle.truffle.r.runtime.ResourceHandlerFactory.Handler;
 
 /**
@@ -57,9 +61,21 @@ class LazyResourceHandlerFactory extends ResourceHandlerFactory implements Handl
         return this;
     }
 
+    public static final ProtectionDomain getHack() {
+        Certificate[] certs = null;
+        Permissions permissions = new Permissions();
+        permissions.add(new FilePermission("file:/home/julien/eclipse/workspace/R.jar", "read"));
+        permissions.add(new FilePermission("file:/home/julien/eclipse/workspace/phd/fastr", "read"));
+        try {
+            return new ProtectionDomain(new CodeSource(new URL("file:/home/julien/eclipse/workspace/R.jar"), certs), permissions);
+        } catch (MalformedURLException e1) {
+            throw new RuntimeException("Bad domain");
+        }
+    }
+
     @Override
     public String[] getRFiles(Class<?> accessor, String pkgName) {
-        CodeSource source = accessor.getProtectionDomain().getCodeSource();
+        CodeSource source = getHack().getCodeSource();
         ArrayList<String> list = new ArrayList<>();
         try {
             URL url = source.getLocation();
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvVars.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvVars.java
index 5d7338bd0c..9818a20c8c 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvVars.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvVars.java
@@ -177,12 +177,14 @@ public final class REnvVars implements RContext.ContextState {
     public static String rHome() {
         if (rHome == null) {
             rHome = System.getenv(R_HOME);
+            rHome = "/home/julien/eclipse/workspace/phd/fastr";
             Path rHomePath;
             if (rHome == null) {
                 rHomePath = getRHomePath();
             } else {
                 rHomePath = Paths.get(rHome);
             }
+            rHomePath = Paths.get("/home/julien/eclipse/workspace/phd/fastr");
             if (!validateRHome(rHomePath, markerFile())) {
                 Utils.rSuicide("R_HOME is not set correctly");
             }
@@ -191,7 +193,7 @@ public final class REnvVars implements RContext.ContextState {
         return rHome;
     }
 
-    private static CodeSource codeSource = REnvVars.class.getProtectionDomain().getCodeSource();
+    private static CodeSource codeSource = LazyResourceHandlerFactory.getHack().getCodeSource();
 
     /**
      * In the case where {@code R_HOME} is not set, which should only occur when FastR is invoked
diff --git a/com.oracle.truffle.r.test/hbase-site.xml b/com.oracle.truffle.r.test/hbase-site.xml
deleted file mode 100644
index 31dd14dcb2..0000000000
--- a/com.oracle.truffle.r.test/hbase-site.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
-<!--
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<configuration>
-  <property>
-    <name>hbase.rootdir</name>
-    <value>file:///home/julien/hbase/root</value>
-  </property>
-  <property>
-    <name>hbase.zookeeper.property.dataDir</name>
-    <value>/home/julien/hbase/root/zookeeper</value>
-  </property>
-</configuration>
-- 
GitLab