From ed14a61bc8405c5aca500e731fd9b26e8c010dd7 Mon Sep 17 00:00:00 2001
From: Zbynek Slajchrt <zbynek.slajchrt@oracle.com>
Date: Mon, 22 Jan 2018 16:18:15 +0100
Subject: [PATCH] R_tryEval upcall fixed

---
 .../r/ffi/impl/common/JavaUpCallsRFFIImpl.java   |  2 +-
 .../truffle/r/ffi/impl/nodes/TryRfEvalNode.java  | 16 ++++++++++++++--
 .../r/ffi/impl/upcalls/StdUpCallsRFFI.java       |  3 ++-
 .../fficall/src/common/rffi_upcalls.h            |  6 ++----
 .../truffle_common/Rinternals_truffle_common.h   |  2 +-
 5 files changed, 20 insertions(+), 9 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 7a2924577a..cab8b5b8df 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
@@ -878,7 +878,7 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    public Object R_tryEval(Object expr, Object env, int silent) {
+    public Object R_tryEval(Object expr, Object env, Object errorFlag, int silent) {
         throw implementedAsNode();
     }
 
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/TryRfEvalNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/TryRfEvalNode.java
index 64d544f386..95d4b2fce0 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/TryRfEvalNode.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/TryRfEvalNode.java
@@ -22,13 +22,19 @@
  */
 package com.oracle.truffle.r.ffi.impl.nodes;
 
+import com.oracle.truffle.api.interop.ForeignAccess;
+import com.oracle.truffle.api.interop.InteropException;
+import com.oracle.truffle.api.interop.Message;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.r.runtime.RErrorHandling;
 
-public class TryRfEvalNode extends FFIUpCallNode.Arg3 {
+public final class TryRfEvalNode extends FFIUpCallNode.Arg4 {
     @Child RfEvalNode rfEvalNode = RfEvalNode.create();
+    @Child Node writeErrorFlagNode = Message.WRITE.createNode();
 
     @Override
-    public Object executeObject(Object expr, Object env, @SuppressWarnings("unused") Object silent) {
+    public Object executeObject(Object expr, Object env, Object errorFlag, @SuppressWarnings("unused") Object silent) {
         Object handlerStack = RErrorHandling.getHandlerStack();
         Object restartStack = RErrorHandling.getRestartStack();
         try {
@@ -36,6 +42,12 @@ public class TryRfEvalNode extends FFIUpCallNode.Arg3 {
             RErrorHandling.resetStacks();
             return rfEvalNode.executeObject(expr, env);
         } catch (Throwable t) {
+            try {
+                ForeignAccess.sendWrite(writeErrorFlagNode, (TruffleObject) errorFlag, 0, 1);
+            } catch (InteropException e) {
+                // Ignore it, when using NFI, e.g., the errorFlag TO does not support the WRITE
+                // message
+            }
             return null;
         } finally {
             RErrorHandling.restoreStacks(handlerStack, restartStack);
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 1f85756b25..599419c4d9 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
@@ -53,6 +53,7 @@ import com.oracle.truffle.r.ffi.impl.nodes.MiscNodes.LENGTHNode;
 import com.oracle.truffle.r.ffi.impl.nodes.RandFunctionsNodes;
 import com.oracle.truffle.r.ffi.impl.nodes.RfEvalNode;
 import com.oracle.truffle.r.ffi.impl.nodes.TryRfEvalNode;
+import com.oracle.truffle.r.ffi.processor.RFFICpointer;
 import com.oracle.truffle.r.ffi.processor.RFFICstring;
 import com.oracle.truffle.r.ffi.processor.RFFIRunGC;
 import com.oracle.truffle.r.ffi.processor.RFFIUpCallNode;
@@ -276,7 +277,7 @@ public interface StdUpCallsRFFI {
 
     @RFFIRunGC
     @RFFIUpCallNode(TryRfEvalNode.class)
-    Object R_tryEval(Object expr, Object env, int silent);
+    Object R_tryEval(Object expr, Object env, @RFFICpointer Object errorFlag, int silent);
 
     Object R_ToplevelExec();
 
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 e5f5f5cfdc..1aaaaa7341 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -221,8 +221,7 @@ typedef Rboolean (*call_R_BindingIsActive)(SEXP sym, SEXP env);
 typedef Rboolean (*call_R_HasFancyBindings)(SEXP rho);
 typedef Rboolean (*call_Rf_isS4)(SEXP x);
 typedef SEXP (*call_Rf_asS4)(SEXP x, Rboolean b, int i);
-typedef SEXP (*call_R_tryEval)(SEXP x, SEXP y, int *ErrorOccurred);
-typedef SEXP (*call_R_tryEvalSilent)(SEXP x, SEXP y, int *ErrorOccurred);
+typedef SEXP (*call_R_tryEval)(SEXP x, SEXP y, int *ErrorOccurred, int silent);
 typedef double (*call_R_atof)(const char *str);
 typedef double (*call_R_strtod)(const char *c, char **end);
 typedef SEXP (*call_R_PromiseExpr)(SEXP x);
@@ -321,4 +320,3 @@ typedef void (*call_R_ReleaseObject)(SEXP x);
 typedef void* (*call_R_alloc)(int n, int size);
 
 #endif
-
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 7a7193a66c..f27bfca6c3 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
@@ -1366,7 +1366,7 @@ SEXP Rf_asS4(SEXP x, Rboolean b, int i) {
 
 static SEXP R_tryEvalInternal(SEXP x, SEXP y, int *ErrorOccurred, int silent) {
     TRACE0();
-    return ((call_R_tryEval) callbacks[R_tryEval_x])(x, y, silent);
+    return ((call_R_tryEval) callbacks[R_tryEval_x])(x, y, ErrorOccurred, silent);
 }
 
 SEXP R_tryEval(SEXP x, SEXP y, int *ErrorOccurred) {
-- 
GitLab