From 41afd94f8dee58c2a72b92402db078e8d01382ae Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Wed, 20 Sep 2017 12:05:17 +0200
Subject: [PATCH] Fix managed build and update documentation

---
 .../r/ffi/impl/managed/Managed_Base.java      | 208 ++++++++++--------
 com.oracle.truffle.r.native/fficall/Makefile  |   2 +
 documentation/dev/managed_ffi.md              |  10 +-
 3 files changed, 123 insertions(+), 97 deletions(-)

diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_Base.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_Base.java
index b9af2ea496..20c7d3f17d 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_Base.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_Base.java
@@ -35,107 +35,123 @@ import java.nio.file.attribute.PosixFilePermissions;
 import java.util.Set;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.ffi.BaseRFFI;
 
 public class Managed_Base implements BaseRFFI {
+
+    private static final class ManagedGetpidNode extends Node implements GetpidNode {
+        private int fakePid = (int) System.currentTimeMillis();
+
+        @Override
+        public int execute() {
+            return fakePid;
+        }
+    }
+
     /**
      * Process id is used as seed for random number generator. We return another "random" number.
      */
     @Override
     public GetpidNode createGetpidNode() {
-        return new GetpidNode() {
-            private int fakePid = (int) System.currentTimeMillis();
+        return new ManagedGetpidNode();
+    }
 
-            @Override
-            public int execute() {
-                return fakePid;
-            }
-        };
+    private static final class ManagedGetwdNode extends Node implements GetwdNode {
+        @Override
+        @TruffleBoundary
+        public String execute() {
+            return Paths.get(".").toAbsolutePath().normalize().toString();
+        }
     }
 
     @Override
     public GetwdNode createGetwdNode() {
-        return new GetwdNode() {
-            @Override
-            @TruffleBoundary
-            public String execute() {
-                return Paths.get(".").toAbsolutePath().normalize().toString();
-            }
-        };
+        return new ManagedGetwdNode();
+    }
+
+    private static final class ManagedSetwdNode extends Node implements SetwdNode {
+        @Override
+        public int execute(String dir) {
+            throw unsupported("setwd");
+        }
     }
 
     @Override
     public SetwdNode createSetwdNode() {
-        return new SetwdNode() {
-            @Override
-            public int execute(String dir) {
-                throw unsupported("setwd");
-            }
-        };
+        return new ManagedSetwdNode();
+    }
+
+    private static final class ManagedMkdirNode extends Node implements MkdirNode {
+        @Override
+        @TruffleBoundary
+        public void execute(String dir, int mode) throws IOException {
+            Set<PosixFilePermission> permissions = permissionsFromMode(mode);
+            Files.createDirectories(Paths.get(dir), PosixFilePermissions.asFileAttribute(permissions));
+        }
     }
 
     @Override
     public MkdirNode createMkdirNode() {
-        return new MkdirNode() {
-            @Override
-            @TruffleBoundary
-            public void execute(String dir, int mode) throws IOException {
-                Set<PosixFilePermission> permissions = permissionsFromMode(mode);
-                Files.createDirectories(Paths.get(dir), PosixFilePermissions.asFileAttribute(permissions));
-            }
-        };
+        return new ManagedMkdirNode();
+    }
+
+    private static final class ManagedReadLinkNode extends Node implements ReadlinkNode {
+        @Override
+        public String execute(String path) throws IOException {
+            throw unsupported("linknode");
+        }
     }
 
     @Override
     public ReadlinkNode createReadlinkNode() {
-        return new ReadlinkNode() {
-            @Override
-            public String execute(String path) throws IOException {
-                throw unsupported("linknode");
+        return new ManagedReadLinkNode();
+    }
+
+    private static final class ManagedMkdtempNode extends Node implements MkdtempNode {
+        @Override
+        @TruffleBoundary
+        public String execute(String template) {
+            Path path = null;
+            boolean done = false;
+            while (!done) {
+                try {
+                    path = Paths.get(template);
+                    Files.createDirectories(path);
+                    done = true;
+                } catch (FileAlreadyExistsException e) {
+                    // nop
+                } catch (IOException e) {
+                    throw RError.error(RError.NO_CALLER, Message.GENERIC, "Cannot create temp directories.");
+                }
             }
-        };
+            return path.toString();
+        }
     }
 
     @Override
     public MkdtempNode createMkdtempNode() {
-        return new MkdtempNode() {
-            @Override
-            @TruffleBoundary
-            public String execute(String template) {
-                Path path = null;
-                boolean done = false;
-                while (!done) {
-                    try {
-                        path = Paths.get(template);
-                        Files.createDirectories(path);
-                        done = true;
-                    } catch (FileAlreadyExistsException e) {
-                        // nop
-                    } catch (IOException e) {
-                        throw RError.error(RError.NO_CALLER, Message.GENERIC, "Cannot create temp directories.");
-                    }
-                }
-                return path.toString();
+        return new ManagedMkdtempNode();
+    }
+
+    private static final class ManagedChmodNode extends Node implements ChmodNode {
+        @Override
+        @TruffleBoundary
+        public int execute(String path, int mode) {
+            try {
+                Files.setPosixFilePermissions(Paths.get(path), permissionsFromMode(mode));
+                return mode;
+            } catch (IOException e) {
+                throw RError.error(RError.NO_CALLER, Message.GENERIC, "Cannot change file permissions.");
             }
-        };
+        }
     }
 
     @Override
     public ChmodNode createChmodNode() {
-        return new ChmodNode() {
-            @Override
-            @TruffleBoundary
-            public int execute(String path, int mode) {
-                try {
-                    Files.setPosixFilePermissions(Paths.get(path), permissionsFromMode(mode));
-                    return mode;
-                } catch (IOException e) {
-                    throw RError.error(RError.NO_CALLER, Message.GENERIC, "Cannot change file permissions.");
-                }
-            }
-        };
+        return new ManagedChmodNode();
     }
 
     @Override
@@ -143,39 +159,41 @@ public class Managed_Base implements BaseRFFI {
         return null;
     }
 
+    private static final class ManagedUnameNode extends Node implements UnameNode {
+        @Override
+        public UtsName execute() {
+            return new UtsName() {
+                @Override
+                public String sysname() {
+                    return System.getProperty("os.name");
+                }
+
+                @Override
+                public String release() {
+                    return "";
+                }
+
+                @Override
+                public String version() {
+                    return System.getProperty("os.version");
+                }
+
+                @Override
+                public String machine() {
+                    return System.getProperty("os.arch");
+                }
+
+                @Override
+                public String nodename() {
+                    return "";
+                }
+            };
+        }
+    }
+
     @Override
     public UnameNode createUnameNode() {
-        return new UnameNode() {
-            @Override
-            public UtsName execute() {
-                return new UtsName() {
-                    @Override
-                    public String sysname() {
-                        return System.getProperty("os.name");
-                    }
-
-                    @Override
-                    public String release() {
-                        return "";
-                    }
-
-                    @Override
-                    public String version() {
-                        return System.getProperty("os.version");
-                    }
-
-                    @Override
-                    public String machine() {
-                        return System.getProperty("os.arch");
-                    }
-
-                    @Override
-                    public String nodename() {
-                        return "";
-                    }
-                };
-            }
-        };
+        return new ManagedUnameNode();
     }
 
     @Override
diff --git a/com.oracle.truffle.r.native/fficall/Makefile b/com.oracle.truffle.r.native/fficall/Makefile
index e39458ddd0..7c8ebc3890 100644
--- a/com.oracle.truffle.r.native/fficall/Makefile
+++ b/com.oracle.truffle.r.native/fficall/Makefile
@@ -101,8 +101,10 @@ else
 ifeq ($(FASTR_RFFI),llvm)
 	$(MAKE) -C src/truffle_llvm clean
 else
+ifneq ($(FASTR_RFFI),managed)
 	$(error unknown value for FASTR_RFFI)
 endif
+endif
 endif
 	rm -rf $(R_LIB)
 	rm -rf fficall.done
diff --git a/documentation/dev/managed_ffi.md b/documentation/dev/managed_ffi.md
index 22f9d046fb..4b0bb169aa 100644
--- a/documentation/dev/managed_ffi.md
+++ b/documentation/dev/managed_ffi.md
@@ -7,8 +7,7 @@ FastR with environment variable `FASTR_RFFI` set to `managed`.
 # Details
 FastR has an 'implementation' of RFFI that does not use any native code directly (e.g. through JNI) and implements only small subset of the API.
 Any usage of the unimplemented parts will cause error at runtime. To enable this RFFI implementation clean build FastR with environment variable
-`FASTR_RFFI` set to *managed* and when running FastR set java property named *fastr.rffi.factory.class* to
-`com.oracle.truffle.r.runtime.ffi.managed.Managed_RFFIFactory`.
+`FASTR_RFFI` set to *managed* and when running FastR set java property named *fastr.rffi.factory.type* to `managed`.
 
 There are additional options that can restrict other usages of native code in FastR:
 
@@ -23,3 +22,10 @@ Following option can be useful for improving security when running FastR:
 
 * Set java property *fastr.objectsize.factory.class*  to `com.oracle.truffle.r.runtime.data.SimpleObjectSizeFactory` to avoid
 usage of otherwise more precise `AgentObjectSizeFactory`, which uses instrumentation agent.
+
+Note that boolean FastR options are passed using syntax R:+/-OptionName. Command line to run FastR with all the
+aforementioned options:
+
+```
+mx --J @'-DR:-LoadPackagesNativeCode -DR:-LoadProfiles -Dfastr.objectsize.factory.class=com.oracle.truffle.r.runtime.data.SimpleObjectSizeFactory -Dfastr.rffi.factory.type=managed' r
+```
-- 
GitLab