From e3ea94248150d1eb725d76b6dc47241270a4de8f Mon Sep 17 00:00:00 2001
From: Florian Angerer <florian.angerer@oracle.com>
Date: Mon, 11 Dec 2017 13:48:09 +0100
Subject: [PATCH] Partially implemented 'R_ToplevelExec'.

---
 .../r/ffi/impl/common/JavaUpCallsRFFIImpl.java        | 10 +++++++++-
 .../truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java    |  2 ++
 .../fficall/src/common/rffi_upcalls.h                 |  3 ++-
 .../fficall/src/common/rffi_upcallsindex.h            |  9 +++++----
 .../src/truffle_common/Rinternals_truffle_common.h    | 11 ++++++++++-
 com.oracle.truffle.r.native/version.source            |  2 +-
 6 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
index cab4934525..c2b3d6e951 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
@@ -42,6 +42,8 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.frame.Frame;
 import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
 import com.oracle.truffle.api.frame.MaterializedFrame;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.interop.java.JavaInterop;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
@@ -55,6 +57,7 @@ import com.oracle.truffle.r.runtime.REnvVars;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RErrorHandling;
+import com.oracle.truffle.r.runtime.RErrorHandling.HandlerStacks;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RSource;
@@ -912,7 +915,12 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     @Override
     @TruffleBoundary
     public Object R_ToplevelExec() {
-        return RErrorHandling.resetAndGetHandlerStacks();
+        return RErrorHandling.resetAndGetHandlerStacks().handlerStack;
+    }
+
+    @Override
+    public void restoreHandlerStacks(Object savedHandlerStack) {
+        RErrorHandling.restoreHandlerStack(savedHandlerStack);
     }
 
     @Override
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
index f8a81aab1f..cfc4c80acb 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
@@ -275,6 +275,8 @@ public interface StdUpCallsRFFI {
 
     Object R_ToplevelExec();
 
+    void restoreHandlerStacks(Object savedHandlerStack);
+
     int RDEBUG(Object x);
 
     void SET_RDEBUG(Object x, int v);
diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
index f7f80924ca..e5f5f5cfdc 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
+++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
@@ -202,7 +202,8 @@ typedef void (*call_DUPLICATE_ATTRIB)(SEXP to, SEXP from);
 typedef int (*call_IS_S4_OBJECT)(SEXP x);
 typedef void (*call_SET_S4_OBJECT)(SEXP x);
 typedef void (*call_UNSET_S4_OBJECT)(SEXP x);
-typedef Rboolean (*call_R_ToplevelExec)(void (*fun)(void *), void *data);
+typedef SEXP (*call_R_ToplevelExec)();
+typedef void (*call_restoreHandlerStack)(SEXP saved_handler_stack);
 typedef void (*call_R_RestoreHashCount)(SEXP rho);
 typedef Rboolean (*call_R_IsPackageEnv)(SEXP rho);
 typedef SEXP (*call_R_PackageEnvName)(SEXP rho);
diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h
index 8008fede3e..cc3ddaf778 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h
+++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h
@@ -173,10 +173,11 @@
 #define octsize_x 168
 #define registerCCallable_x 169
 #define registerRoutines_x 170
-#define setDotSymbolValues_x 171
-#define unif_rand_x 172
-#define useDynamicSymbols_x 173
+#define restoreHandlerStacks_x 171
+#define setDotSymbolValues_x 172
+#define unif_rand_x 173
+#define useDynamicSymbols_x 174
 
-#define UPCALLS_TABLE_SIZE 174
+#define UPCALLS_TABLE_SIZE 175
 
 #endif // RFFI_UPCALLSINDEX_H
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
index c69fd861ca..c305453c28 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
@@ -1253,7 +1253,16 @@ void UNSET_S4_OBJECT(SEXP x) {
 
 Rboolean R_ToplevelExec(void (*fun)(void *), void *data) {
     TRACE0();
-    return (Rboolean) unimplemented("R_ToplevelExec");
+
+    // reset handler stack
+    SEXP saved_handler_stack = ((call_R_ToplevelExec) callbacks[R_ToplevelExec_x])();
+    checkExitCall();
+    fun(data);
+    ((call_restoreHandlerStack) callbacks[restoreHandlerStacks_x])(saved_handler_stack);
+    checkExitCall();
+
+    // TODO detect errors
+    return TRUE;
 }
 
 SEXP R_ExecWithCleanup(SEXP (*fun)(void *), void *data,
diff --git a/com.oracle.truffle.r.native/version.source b/com.oracle.truffle.r.native/version.source
index 9e5feb5256..abac1ea7b7 100644
--- a/com.oracle.truffle.r.native/version.source
+++ b/com.oracle.truffle.r.native/version.source
@@ -1 +1 @@
-46
+47
-- 
GitLab