diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java
index 25dd64ff7977d1cae004fd2689f1500d9070ecc8..4803d069f7f944137fb0b2b03e91f2e4b72cd5f2 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java
@@ -23,6 +23,7 @@
 package com.oracle.truffle.r.nodes.access;
 
 import com.oracle.truffle.api.CompilerAsserts;
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.NodeChild;
 import com.oracle.truffle.api.frame.Frame;
 import com.oracle.truffle.api.frame.FrameSlot;
@@ -32,7 +33,10 @@ import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
+import com.oracle.truffle.r.nodes.function.call.RExplicitCallNode;
+import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RShareable;
 import com.oracle.truffle.r.runtime.env.frame.ActiveBinding;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
@@ -51,6 +55,8 @@ abstract class BaseWriteVariableNode extends WriteVariableNode {
         super(name);
     }
 
+    @Child private RExplicitCallNode writeActiveBinding;
+
     private final ConditionProfile isObjectProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile isCurrentProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile isShareableProfile = ConditionProfile.createBinaryProfile();
@@ -178,7 +184,16 @@ abstract class BaseWriteVariableNode extends WriteVariableNode {
         }
 
         if (isActiveBindingProfile.profile(object != null && ActiveBinding.isActiveBinding(object))) {
-            return ((ActiveBinding) object).writeValue(value);
+            if (writeActiveBinding == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                writeActiveBinding = insert(RExplicitCallNode.create());
+            }
+            ActiveBinding binding = (ActiveBinding) object;
+            try {
+                return writeActiveBinding.execute(execFrame, binding.getFunction(), new RArgsValuesAndNames(new Object[]{value}, ArgumentsSignature.empty(1)));
+            } finally {
+                binding.setInitialized();
+            }
         } else {
             Object newValue = shareObjectValue(lookupFrame, frameSlot, storedObjectProfile.profile(value), mode, false);
             FrameSlotChangeMonitor.setObjectAndInvalidate(lookupFrame, frameSlot, newValue, false, invalidateProfile);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java
index 12cbdee57697a38ca4988baeaebd72f4e6ab5d7c..f3e42feefcbbb14c573b303dd54de1c038a5905e 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java
@@ -35,7 +35,9 @@ import com.oracle.truffle.api.nodes.UnexpectedResultException;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode;
+import com.oracle.truffle.r.nodes.function.call.RExplicitCallNode;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RTypesGen;
@@ -45,6 +47,7 @@ import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 public final class LocalReadVariableNode extends Node {
 
     @Child private PromiseHelperNode promiseHelper;
+    @Child private RExplicitCallNode readActiveBinding;
 
     private final Object identifier;
     private final boolean forceResult;
@@ -120,7 +123,15 @@ public final class LocalReadVariableNode extends Node {
         }
         // special treatment for active binding: call bound function
         if (!containsNoActiveBindingAssumption.isValid() && ActiveBinding.isActiveBinding(result)) {
-            Object readValue = ((ActiveBinding) result).readValue();
+            if (readActiveBinding == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                readActiveBinding = insert(RExplicitCallNode.create());
+            }
+            ActiveBinding binding = (ActiveBinding) result;
+            if (binding.isHidden() && !binding.isInitialized()) {
+                return null;
+            }
+            Object readValue = readActiveBinding.execute(frame, binding.getFunction(), RArgsValuesAndNames.EMPTY);
             if (readValue == RMissing.instance) {
                 return null;
             }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
index 0eab69dc38f083cb4dbc5da0a296d49c41c87ecc..5a8268ee382dbd27746ed780b094ae0828bef458 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
@@ -48,6 +48,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode;
+import com.oracle.truffle.r.nodes.function.call.RExplicitCallNode;
 import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.FastROptions;
@@ -107,8 +108,11 @@ final class LookupNode extends RSourceSectionNode implements RSyntaxNode, RSynta
             CompilerDirectives.transferToInterpreterAndInvalidate();
             visibility = insert(SetVisibilityNode.create());
         }
-        visibility.execute(frame, true);
-        return read.executeInternal(frame, frame);
+        try {
+            return read.executeInternal(frame, frame);
+        } finally {
+            visibility.execute(frame, true);
+        }
     }
 
     @Override
@@ -180,6 +184,7 @@ public final class ReadVariableNode extends RBaseNode {
 
     @Child private PromiseHelperNode promiseHelper;
     @Child private CheckTypeNode checkTypeNode;
+    @Child private RExplicitCallNode readActiveBinding;
 
     @CompilationFinal private FrameLevel read;
     @CompilationFinal private boolean needsCopying;
@@ -252,16 +257,25 @@ public final class ReadVariableNode extends RBaseNode {
             }
         }
         if (needsCopying && copyProfile.profile(result instanceof RAbstractVector)) {
-            result = ((RAbstractVector) result).copy();
+            return ((RAbstractVector) result).copy();
         }
         if (isPromiseProfile.profile(result instanceof RPromise)) {
             if (promiseHelper == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
                 promiseHelper = insert(new PromiseHelperNode());
             }
-            result = promiseHelper.evaluate(frame, (RPromise) result);
-        } else if (isActiveBindingProfile.profile(ActiveBinding.isActiveBinding(result))) {
-            Object readValue = ((ActiveBinding) result).readValue();
+            return promiseHelper.evaluate(frame, (RPromise) result);
+        }
+        if (isActiveBindingProfile.profile(ActiveBinding.isActiveBinding(result))) {
+            if (readActiveBinding == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                readActiveBinding = insert(RExplicitCallNode.create());
+            }
+            ActiveBinding binding = (ActiveBinding) result;
+            if (binding.isHidden() && !binding.isInitialized()) {
+                throw error(mode == RType.Function ? RError.Message.UNKNOWN_FUNCTION : RError.Message.UNKNOWN_OBJECT, identifier);
+            }
+            Object readValue = readActiveBinding.execute(frame, binding.getFunction(), RArgsValuesAndNames.EMPTY);
             if (readValue == RMissing.instance) {
                 throw error(mode == RType.Function ? RError.Message.UNKNOWN_FUNCTION : RError.Message.UNKNOWN_OBJECT, identifier);
             }