diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java
index 3da7a4f3d7d028bd017e67977844a76da85ee241..5ebc1526540a534bb45e1b1645e0bee0f0751f85 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java
@@ -28,6 +28,7 @@ import java.util.List;
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.ExplodeLoop;
+import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.r.nodes.control.OperatorNode;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode;
@@ -78,10 +79,20 @@ public abstract class InternalNode extends OperatorNode {
      */
     private static final class InternalUninitializedNode extends InternalNode {
 
+        // whether arguments need to be copied
+        private boolean needsCopy;
+
         InternalUninitializedNode(SourceSection src, RSyntaxLookup operator, ArgumentsSignature outerSignature, RSyntaxNode[] outerArgs) {
             super(src, operator, outerSignature, outerArgs);
         }
 
+        @Override
+        public Node copy() {
+            InternalUninitializedNode copy = (InternalUninitializedNode) super.copy();
+            copy.needsCopy = true;
+            return copy;
+        }
+
         @Override
         public Object execute(VirtualFrame frame) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -125,6 +136,12 @@ public abstract class InternalNode extends OperatorNode {
 
             RBuiltinFactory factory = (RBuiltinFactory) function.getRBuiltin();
             RSyntaxElement[] callArgs = call.getSyntaxArguments();
+            if (needsCopy) {
+                callArgs = callArgs.clone();
+                for (int i = 0; i < callArgs.length; i++) {
+                    callArgs[i] = RContext.getASTBuilder().process(callArgs[i]);
+                }
+            }
 
             // verify the number of arguments
             if (factory.getSignature().getVarArgCount() == 0) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
index d2e30dd9e8bdbe712eeb9a886affff2551e83603..1e8e2bde3ee39f7f4a566aa76d2c0ca9fb44e9c9 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -87,7 +87,6 @@ import com.oracle.truffle.r.runtime.RVisibility;
 import com.oracle.truffle.r.runtime.SubstituteVirtualFrame;
 import com.oracle.truffle.r.runtime.builtins.FastPathFactory;
 import com.oracle.truffle.r.runtime.builtins.RBuiltinDescriptor;
-import com.oracle.truffle.r.runtime.builtins.RBuiltinKind;
 import com.oracle.truffle.r.runtime.conn.RConnection;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
@@ -543,51 +542,6 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
         return CallArgumentsNode.create(modeChange, modeChangeAppliesToAll, args, signature, varArgIndexes);
     }
 
-    /**
-     * Creates a call to a resolved {@link RBuiltinKind#INTERNAL} that will be used to replace the
-     * original call.
-     *
-     * @param internalCallArg the {@link RCallNode} corresponding to the argument to the {code
-     *            .Internal}.
-     * @param function the resolved {@link RFunction}.
-     */
-    public static RNode createInternalCall(RCallNode internalCallArg, RFunction function) {
-        CompilerAsserts.neverPartOfCompilation();
-        return new InternalNode(FunctionDispatchNodeGen.create(internalCallArg, false, null), function, internalCallArg.lookupVarArgs != null);
-    }
-
-    @NodeInfo(cost = NodeCost.NONE)
-    private static final class InternalNode extends RNode {
-        @Child private FunctionDispatch rootCallNode;
-        @Child private ReadVariableNode lookupVarArgs;
-        private final RFunction function;
-
-        InternalNode(FunctionDispatch rootCallNode, RFunction function, boolean needsVarArgLookup) {
-            this.rootCallNode = rootCallNode;
-            this.function = function;
-            this.lookupVarArgs = needsVarArgLookup ? ReadVariableNode.createSilent(ArgumentsSignature.VARARG_NAME, RType.Any) : null;
-        }
-
-        private RArgsValuesAndNames lookupVarArgs(VirtualFrame frame) {
-            RArgsValuesAndNames varArgs;
-            if (lookupVarArgs == null) {
-                varArgs = null;
-            } else {
-                try {
-                    varArgs = lookupVarArgs.executeRArgsValuesAndNames(frame);
-                } catch (UnexpectedResultException e) {
-                    throw RError.error(RError.SHOW_CALLER, RError.Message.NO_DOT_DOT_DOT);
-                }
-            }
-            return varArgs;
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame) {
-            return rootCallNode.execute(frame, function, lookupVarArgs(frame), null, null);
-        }
-    }
-
     /**
      * Creates a modified call in which the first N arguments are replaced by
      * {@code replacementArgs}. This is only used to support