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 eeb5dd0ceb3c25f714e58b1751a5d3bd2fcce3e7..7a2924577a1ebe8a2f65a0c61e6ee89d054c99b9 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,20 +878,8 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    @TruffleBoundary
     public Object R_tryEval(Object expr, Object env, int silent) {
-        Object handlerStack = RErrorHandling.getHandlerStack();
-        Object restartStack = RErrorHandling.getRestartStack();
-        try {
-            // TODO handle silent
-            RErrorHandling.resetStacks();
-            Object result = Rf_eval(expr, env);
-            return result;
-        } catch (Throwable t) {
-            return null;
-        } finally {
-            RErrorHandling.restoreStacks(handlerStack, restartStack);
-        }
+        throw implementedAsNode();
     }
 
     /**
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RfEvalNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RfEvalNode.java
index da3d249e0dd4c25c4e487cfc76c9b701741ce7a8..ae738c977aec0e2f50ad9a5e728cbfe0f2a17a03 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RfEvalNode.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RfEvalNode.java
@@ -65,13 +65,13 @@ public abstract class RfEvalNode extends FFIUpCallNode.Arg2 {
     @Specialization
     @TruffleBoundary
     Object handleExpression(RExpression expr, REnvironment env) {
-        return RContext.getEngine().eval(expr, env, RCaller.topLevel);
+        return RContext.getEngine().eval(expr, env, null);
     }
 
     @Specialization
     @TruffleBoundary
     Object handleLanguage(RLanguage expr, REnvironment env) {
-        return RContext.getEngine().eval(expr, env, RCaller.topLevel);
+        return RContext.getEngine().eval(expr, env, null);
     }
 
     @Specialization
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
new file mode 100644
index 0000000000000000000000000000000000000000..64d544f386ddc03116d3f24d580109a1e6988993
--- /dev/null
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/TryRfEvalNode.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.ffi.impl.nodes;
+
+import com.oracle.truffle.r.runtime.RErrorHandling;
+
+public class TryRfEvalNode extends FFIUpCallNode.Arg3 {
+    @Child RfEvalNode rfEvalNode = RfEvalNode.create();
+
+    @Override
+    public Object executeObject(Object expr, Object env, @SuppressWarnings("unused") Object silent) {
+        Object handlerStack = RErrorHandling.getHandlerStack();
+        Object restartStack = RErrorHandling.getRestartStack();
+        try {
+            // TODO handle silent
+            RErrorHandling.resetStacks();
+            return rfEvalNode.executeObject(expr, env);
+        } catch (Throwable t) {
+            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 90dba617d41e82a72eb5964bd987e6f026d72731..1f85756b25d0f1bdc1752c47bdc0b3ce200eddeb 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
@@ -52,6 +52,7 @@ import com.oracle.truffle.r.ffi.impl.nodes.MiscNodes;
 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.RFFICstring;
 import com.oracle.truffle.r.ffi.processor.RFFIRunGC;
 import com.oracle.truffle.r.ffi.processor.RFFIUpCallNode;
@@ -273,6 +274,8 @@ public interface StdUpCallsRFFI {
 
     void Rf_copyMatrix(Object s, Object t, int byrow);
 
+    @RFFIRunGC
+    @RFFIUpCallNode(TryRfEvalNode.class)
     Object R_tryEval(Object expr, Object env, int silent);
 
     Object R_ToplevelExec();
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 c305453c283d0c934e99e13942a7399d78aabf1d..7a7193a66caef511c33b627cc3f3640e9d032a75 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();
-    unimplemented("R_tryEvalInternal");
+    return ((call_R_tryEval) callbacks[R_tryEval_x])(x, y, silent);
 }
 
 SEXP R_tryEval(SEXP x, SEXP y, int *ErrorOccurred) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java
index 01d7eaa01723bbeef0689b6981dc96b6ef27f790..906f67906eb3c1dad6bc7903825c1530c41e04e9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java
@@ -48,6 +48,7 @@ import com.oracle.truffle.r.nodes.builtin.base.GetFunctionsFactory.GetNodeGen;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode;
 import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
+import com.oracle.truffle.r.runtime.RArguments;
 import com.oracle.truffle.r.runtime.RCaller;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RType;
@@ -170,8 +171,8 @@ public abstract class Eval extends RBuiltinNode.Arg3 {
 
     @Specialization
     protected Object doEval(VirtualFrame frame, RLanguage expr, Object envir, Object enclos) {
-        RCaller rCaller = RCaller.create(frame, getOriginalCall());
         REnvironment environment = envCast.execute(frame, envir, enclos);
+        RCaller rCaller = getCaller(frame, environment);
         try {
             return RContext.getEngine().eval(expr, environment, rCaller);
         } catch (ReturnException ret) {
@@ -187,8 +188,8 @@ public abstract class Eval extends RBuiltinNode.Arg3 {
 
     @Specialization
     protected Object doEval(VirtualFrame frame, RExpression expr, Object envir, Object enclos) {
-        RCaller rCaller = RCaller.create(frame, getOriginalCall());
         REnvironment environment = envCast.execute(frame, envir, enclos);
+        RCaller rCaller = getCaller(frame, environment);
         try {
             return RContext.getEngine().eval(expr, environment, rCaller);
         } catch (ReturnException ret) {
@@ -272,4 +273,12 @@ public abstract class Eval extends RBuiltinNode.Arg3 {
         visibility.execute(frame, true);
         return expr;
     }
+
+    private RCaller getCaller(VirtualFrame frame, REnvironment environment) {
+        if (environment instanceof REnvironment.Function) {
+            return RArguments.getCall(environment.getFrame());
+        } else {
+            return RCaller.create(frame, getOriginalCall());
+        }
+    }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/VirtualEvalFrame.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/VirtualEvalFrame.java
index 7eae87ef3866b9eb754f29a2c251b42923662118..336a2cf0b0154fd749988d7fce63335750014419 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/VirtualEvalFrame.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/VirtualEvalFrame.java
@@ -99,7 +99,12 @@ public abstract class VirtualEvalFrame extends SubstituteVirtualFrame implements
         Object[] arguments = Arrays.copyOf(originalFrame.getArguments(), originalFrame.getArguments().length);
         arguments[RArguments.INDEX_IS_IRREGULAR] = true;
         arguments[RArguments.INDEX_FUNCTION] = function;
-        arguments[RArguments.INDEX_CALL] = call;
+        if (call != null) {
+            // Otherwise leave here the call from originalFrame
+            arguments[RArguments.INDEX_CALL] = call;
+        } else if (arguments[RArguments.INDEX_CALL] == null) {
+            arguments[RArguments.INDEX_CALL] = RCaller.topLevel;
+        }
         MaterializedFrame unwrappedFrame = originalFrame instanceof SubstituteVirtualFrame ? ((SubstituteVirtualFrame) originalFrame).getOriginalFrame() : originalFrame;
         @SuppressWarnings("unchecked")
         Class<MaterializedFrame> clazz = (Class<MaterializedFrame>) unwrappedFrame.getClass();
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java
index b31e710df2030d6d11415e6dfa360c7c3839b3d3..fda95437ebad45eeaccbaf9d2d422317f3ed76c4 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java
@@ -199,12 +199,14 @@ public interface Engine {
     Object parseAndEval(Source sourceDesc, MaterializedFrame frame, boolean printResult) throws ParseException;
 
     /**
-     * Support for the {@code eval} {@code .Internal}.
+     * Support for the {@code eval} {@code .Internal}. If the {@code caller} argument is null, it is
+     * taken from the environment's frame.
      */
     Object eval(RExpression expr, REnvironment envir, RCaller caller);
 
     /**
      * Variant of {@link #eval(RExpression, REnvironment, RCaller)} for a single language element.
+     * If the {@code caller} argument is null, it is taken from the environment's frame.
      */
     Object eval(RLanguage expr, REnvironment envir, RCaller caller);
 
diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R
index f74c7dce9e87076fa28e95d4f7281f5001495bf2..cf85ab25b37bee4c3d962a1907f945a09187c62d 100644
--- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R
+++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R
@@ -45,6 +45,21 @@ promiseInfo <- foo(tmp)
 stopifnot('some_unique_name' %in% ls(promiseInfo[[2]]))
 eval(promiseInfo[[1]], promiseInfo[[2]])
 
+# parent.frame call in Rf_eval. Simulates pattern from rlang package
+getCurrEnv <- function(r = parent.frame()) r
+fn <- function(eval_fn) {
+  list(middle(eval_fn), getCurrEnv())
+}
+middle <- function(eval_fn) {
+  deep(eval_fn, getCurrEnv())
+}
+deep <- function(eval_fn, eval_env) {
+  # the result value of rffi.tryEval is list, first element is the actual result
+  eval_fn(quote(parent.frame()), eval_env)[[1]]
+}
+res <- fn(rffi.tryEval)
+stopifnot(identical(res[[1]], res[[2]]))
+
 # fiddling the pointers to the native arrays: we get data pointer to the first SEXP argument (vec),
 # then put value 42/TRUE directly into it at index 0,
 # value of symbol 'myvar' through Rf_eval at index 1,
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index 1589d9a4709b19317a4c41ff9db479ca6ab967d2..cc7e4e4fea9a0a6c3a0e75245573104b2bb8a1ae 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -25299,6 +25299,13 @@ x
 #{ ne <- new.env(); evalq(x <- 1, ne); ls(ne) }
 [1] "x"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_eval.testEvalVisibility#
+#eval(parse(text='1+1'))
+[1] 2
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_eval.testEvalVisibility#
+#eval(parse(text='x<-1'))
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_eval.testReturnInEvalExpr#
 #f1 <- function(x) { eval(quote(if(x>2){return()}else 1)); 10 };f1(5);f1(0)
 [1] 10
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java
index 55adc7d42e2b2566e2abe645d2fab23070a85a6c..fc2a2d8923fec2e133c1af559ba429a42d54e5e9 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java
@@ -68,4 +68,10 @@ public class TestBuiltin_eval extends TestBase {
     public void testReturnInEvalExpr() {
         assertEval("f1 <- function(x) { eval(quote(if(x>2){return()}else 1)); 10 };f1(5);f1(0)");
     }
+
+    @Test
+    public void testEvalVisibility() {
+        assertEval("eval(parse(text='x<-1'))");
+        assertEval("eval(parse(text='1+1'))");
+    }
 }