diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
index 986d0bebe7fae527b2c137e375148ddde6287f69..d1e476680c5d60a199e2e767fa501189b929b4b0 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
@@ -52,7 +52,6 @@ import com.oracle.truffle.r.nodes.builtin.helpers.DebugHandling;
 import com.oracle.truffle.r.nodes.builtin.helpers.TraceHandling;
 import com.oracle.truffle.r.nodes.control.AbstractLoopNode;
 import com.oracle.truffle.r.nodes.control.BlockNode;
-import com.oracle.truffle.r.nodes.control.ForNode;
 import com.oracle.truffle.r.nodes.control.IfNode;
 import com.oracle.truffle.r.nodes.control.ReplacementDispatchNode;
 import com.oracle.truffle.r.nodes.function.ClassHierarchyNode;
@@ -278,7 +277,7 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
         if (obj instanceof RLanguage) {
             return (RNode) RASTUtils.unwrap(((RLanguage) obj).getRep());
         } else if (obj instanceof RSymbol) {
-            return ReadVariableNode.create(((RSymbol) obj).getName());
+            return RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, ((RSymbol) obj).getName(), false).asRNode();
         } else if (obj instanceof RPromise) {
             // Evaluate promise and return the result as constant.
             return ConstantNode.create(forcePromise("unwrapToRNode", objArg));
@@ -538,7 +537,7 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
                     // single statement block, variable parent
                     // note: RepeatingNode is not a RSyntaxElement but the body of a loop is
                     // under the repeating node !
-                    return parent instanceof FunctionDefinitionNode || parent instanceof RootWithBody || parent instanceof IfNode || parent instanceof AbstractLoopNode || ForNode.isLoopBody(node);
+                    return parent instanceof FunctionDefinitionNode || parent instanceof RootWithBody || parent instanceof IfNode || AbstractLoopNode.isLoopBody(node);
                 }
             }
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java
index a341a6efac5843df1dbde167cb8e1136d3197477..af54167a56d972f79e53d073ec2feaa8d3290727 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java
@@ -462,11 +462,11 @@ public class MethodsListDispatch {
 
             }
             RCallNode callNode = (RCallNode) matchedCall.getRep();
-            RNode f = ReadVariableNode.create(RRuntime.R_DOT_NEXT_METHOD);
+            RNode f = RContext.getASTBuilder().lookup(RSyntaxNode.SOURCE_UNAVAILABLE, RRuntime.R_DOT_NEXT_METHOD, false).asRNode();
             ArgumentsSignature sig = callNode.getSyntaxSignature();
             RSyntaxNode[] args = new RSyntaxNode[sig.getLength()];
             for (int i = 0; i < args.length; i++) {
-                args[i] = ReadVariableNode.create(sig.getName(i));
+                args[i] = RContext.getASTBuilder().lookup(RSyntaxNode.SOURCE_UNAVAILABLE, sig.getName(i), false);
             }
             RLanguage newCall = RDataFactory.createLanguage(RCallNode.createCall(RSyntaxNode.SOURCE_UNAVAILABLE, f, sig, args));
             Object res = RContext.getEngine().eval(newCall, ev.getFrame());
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java
index e30395040f735c521a1dd289a154b3dd156b239f..c413058b6ab4cfa40077c3a83a6131f5788b3cbf 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java
@@ -216,7 +216,7 @@ public abstract class Deriv extends RExternalBuiltinNode {
         int nexpr = exprlist.size();
 
         if (fIndex > 0) {
-            exprlist.add(ReadVariableNode.create(tag + fIndex));
+            exprlist.add(createLookup(tag + fIndex));
         } else {
             exprlist.add(cloneElement(elem.asRSyntaxNode()));
         }
@@ -228,13 +228,13 @@ public abstract class Deriv extends RExternalBuiltinNode {
 
         for (int i = 0, k = 0; i < nderiv; i++) {
             if (dIndex[i] > 0) {
-                exprlist.add(ReadVariableNode.create(tag + dIndex[i]));
+                exprlist.add(createLookup(tag + dIndex[i]));
 
                 if (hessian) {
                     RBaseNode dExpr = d(elem, names.getDataAt(i));
                     for (int j = i; j < nderiv; j++) {
                         if (d2Index[k] > 0) {
-                            exprlist.add(ReadVariableNode.create(tag + d2Index[k]));
+                            exprlist.add(createLookup(tag + d2Index[k]));
                         } else {
                             exprlist.add((RSyntaxNode) d(dExpr, names.getDataAt(j)));
                         }
@@ -250,7 +250,7 @@ public abstract class Deriv extends RExternalBuiltinNode {
                 if (hessian) {
                     for (int j = i; j < nderiv; j++) {
                         if (d2Index[k] > 0) {
-                            exprlist.add(ReadVariableNode.create(tag + d2Index[k]));
+                            exprlist.add(createLookup(tag + d2Index[k]));
                         } else {
                             RBaseNode d2Expr = d(dExpr, names.getDataAt(j));
                             if (isZero((RSyntaxElement) d2Expr)) {
@@ -313,7 +313,7 @@ public abstract class Deriv extends RExternalBuiltinNode {
         }
 
         // .value
-        exprlist.set(p++, ReadVariableNode.create(".value"));
+        exprlist.set(p++, createLookup(".value"));
 
         // prune exprlist
         exprlist.removeAll(Collections.singleton(null));
@@ -322,7 +322,7 @@ public abstract class Deriv extends RExternalBuiltinNode {
         for (RSyntaxNode e : exprlist) {
             blockStatements.add(RCodeBuilder.argument(e));
         }
-        RSyntaxNode blockCall = RContext.getASTBuilder().call(RSyntaxNode.LAZY_DEPARSE, ReadVariableNode.create("{"), blockStatements);
+        RSyntaxNode blockCall = RContext.getASTBuilder().call(RSyntaxNode.LAZY_DEPARSE, createLookup("{"), blockStatements);
 
         if (functionArg instanceof RAbstractStringVector) {
             RAbstractStringVector funArgNames = (RAbstractStringVector) functionArg;
@@ -373,7 +373,7 @@ public abstract class Deriv extends RExternalBuiltinNode {
                 for (int i = 0; i < args.length; i++) {
                     int k = accept(args[i]);
                     if (k > 0) {
-                        newArgs.add(RCodeBuilder.argument(ReadVariableNode.create(tag + k)));
+                        newArgs.add(RCodeBuilder.argument(createLookup(tag + k)));
                     } else {
                         newArgs.add(RCodeBuilder.argument(cloneElement(args[i])));
                     }
@@ -522,9 +522,9 @@ public abstract class Deriv extends RExternalBuiltinNode {
 
     static RSyntaxNode newCall(String functionName, RSyntaxElement arg1, RSyntaxElement arg2) {
         if (arg2 == null) {
-            return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create(functionName), (RSyntaxNode) arg1);
+            return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup(functionName), (RSyntaxNode) arg1);
         } else {
-            return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create(functionName), (RSyntaxNode) arg1, (RSyntaxNode) arg2);
+            return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup(functionName), (RSyntaxNode) arg1, (RSyntaxNode) arg2);
         }
     }
 
@@ -614,24 +614,28 @@ public abstract class Deriv extends RExternalBuiltinNode {
         replace(subexprName, replacement, exprlist, fromIndex + 1);
     }
 
+    private static RSyntaxNode createLookup(String name) {
+        return RContext.getASTBuilder().lookup(RSyntaxNode.SOURCE_UNAVAILABLE, name, false);
+    }
+
     private static RSyntaxNode createAssignNode(String varName, RSyntaxNode rhs) {
-        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), ReadVariableNode.create(varName.intern()), addParens(rhs));
+        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("<-"), createLookup(varName.intern()), addParens(rhs));
     }
 
     private static RSyntaxNode hessAssign1(String varName, RSyntaxNode rhs) {
-        RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("["), ReadVariableNode.create(".hessian"), ConstantNode.create(REmpty.instance),
+        RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("["), createLookup(".hessian"), ConstantNode.create(REmpty.instance),
                         ConstantNode.create(varName.intern()), ConstantNode.create(varName.intern()));
-        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp, rhs);
+        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("<-"), tmp, rhs);
     }
 
     private static RSyntaxNode hessAssign2(String varName1, String varName2, RSyntaxNode rhs) {
-        RSyntaxNode tmp1 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("["), ReadVariableNode.create(".hessian"), ConstantNode.create(REmpty.instance),
+        RSyntaxNode tmp1 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("["), createLookup(".hessian"), ConstantNode.create(REmpty.instance),
                         ConstantNode.create(varName1.intern()), ConstantNode.create(varName2.intern()));
-        RSyntaxNode tmp2 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("["), ReadVariableNode.create(".hessian"), ConstantNode.create(REmpty.instance),
+        RSyntaxNode tmp2 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("["), createLookup(".hessian"), ConstantNode.create(REmpty.instance),
                         ConstantNode.create(varName2.intern()), ConstantNode.create(varName1.intern()));
 
-        RSyntaxNode tmp3 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp2, rhs);
-        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp1, tmp3);
+        RSyntaxNode tmp3 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("<-"), tmp2, rhs);
+        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("<-"), tmp1, tmp3);
     }
 
     private static RSyntaxNode createGrad(RAbstractStringVector names) {
@@ -640,15 +644,15 @@ public abstract class Deriv extends RExternalBuiltinNode {
         for (int i = 0; i < n; i++) {
             cArgs.add(RCodeBuilder.argument(ConstantNode.create(names.getDataAt(i).intern())));
         }
-        RSyntaxNode tmp1 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("c"), cArgs);
-        RSyntaxNode dimnames = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("list"), ConstantNode.create(RNull.instance), tmp1);
+        RSyntaxNode tmp1 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("c"), cArgs);
+        RSyntaxNode dimnames = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("list"), ConstantNode.create(RNull.instance), tmp1);
 
-        RSyntaxNode tmp2 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("length"), ReadVariableNode.create(".value"));
-        RSyntaxNode dim = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("c"), tmp2, ConstantNode.create(n));
+        RSyntaxNode tmp2 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("length"), createLookup(".value"));
+        RSyntaxNode dim = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("c"), tmp2, ConstantNode.create(n));
         ConstantNode data = ConstantNode.create(0.);
 
-        RSyntaxNode p = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("array"), data, dim, dimnames);
-        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), ReadVariableNode.create(".grad"), p);
+        RSyntaxNode p = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("array"), data, dim, dimnames);
+        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("<-"), createLookup(".grad"), p);
     }
 
     private static RSyntaxNode createHess(RAbstractStringVector names) {
@@ -657,32 +661,32 @@ public abstract class Deriv extends RExternalBuiltinNode {
         for (int i = 0; i < n; i++) {
             cArgs.add(RCodeBuilder.argument(ConstantNode.create(names.getDataAt(i).intern())));
         }
-        RSyntaxNode tmp1 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("c"), cArgs);
+        RSyntaxNode tmp1 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("c"), cArgs);
         RSyntaxNode tmp1Clone = cloneElement(tmp1);
-        RSyntaxNode dimnames = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("list"), ConstantNode.create(RNull.instance), tmp1, tmp1Clone);
+        RSyntaxNode dimnames = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("list"), ConstantNode.create(RNull.instance), tmp1, tmp1Clone);
 
-        RSyntaxNode tmp2 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("length"), ReadVariableNode.create(".value"));
-        RSyntaxNode dim = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("c"), tmp2, ConstantNode.create(n), ConstantNode.create(n));
+        RSyntaxNode tmp2 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("length"), createLookup(".value"));
+        RSyntaxNode dim = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("c"), tmp2, ConstantNode.create(n), ConstantNode.create(n));
         ConstantNode data = ConstantNode.create(0.);
 
-        RSyntaxNode p = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("array"), data, dim, dimnames);
-        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), ReadVariableNode.create(".hessian"), p);
+        RSyntaxNode p = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("array"), data, dim, dimnames);
+        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("<-"), createLookup(".hessian"), p);
     }
 
     private static RSyntaxNode derivAssign(String name, RSyntaxNode expr) {
-        RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("["), ReadVariableNode.create(".grad"), ConstantNode.create(REmpty.instance),
+        RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("["), createLookup(".grad"), ConstantNode.create(REmpty.instance),
                         ConstantNode.create(name.intern()));
-        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp, expr);
+        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("<-"), tmp, expr);
     }
 
     private static RSyntaxNode addGrad() {
-        RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("attr"), ReadVariableNode.create(".value"), ConstantNode.create("gradient"));
-        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp, ReadVariableNode.create(".grad"));
+        RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("attr"), createLookup(".value"), ConstantNode.create("gradient"));
+        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("<-"), tmp, createLookup(".grad"));
     }
 
     private static RSyntaxNode addHess() {
-        RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("attr"), ReadVariableNode.create(".value"), ConstantNode.create("hessian"));
-        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp, ReadVariableNode.create(".hessian"));
+        RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("attr"), createLookup(".value"), ConstantNode.create("hessian"));
+        return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, createLookup("<-"), tmp, createLookup(".hessian"));
     }
 
     private static boolean isForm(RSyntaxElement expr, String functionName) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
index 98d1def9c8a29e78cdaf166ba10831f182b81e39..6f9d7397c1b608445af908913e2243fe6c0ff088 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
@@ -32,9 +32,7 @@ import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.FrameDescriptor;
 import com.oracle.truffle.r.nodes.access.AccessArgumentNode;
-import com.oracle.truffle.r.nodes.access.ConstantNode;
 import com.oracle.truffle.r.nodes.access.WriteVariableNode;
-import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.function.FormalArguments;
 import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode;
@@ -45,6 +43,7 @@ import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExpression;
@@ -96,7 +95,7 @@ public abstract class AsFunction extends RBuiltinNode.Arg2 {
                 if (arg == RMissing.instance) {
                     defaultValue = null;
                 } else if (arg == RNull.instance) {
-                    defaultValue = ConstantNode.create(RNull.instance);
+                    defaultValue = RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, RNull.instance).asRNode();
                 } else if (arg instanceof RLanguage) {
                     defaultValue = (RNode) ((RLanguage) arg).getRep();
                 } else if (arg instanceof RSymbol) {
@@ -104,10 +103,10 @@ public abstract class AsFunction extends RBuiltinNode.Arg2 {
                     if (symbol.isMissing()) {
                         defaultValue = null;
                     } else {
-                        defaultValue = ReadVariableNode.create(symbol.getName());
+                        defaultValue = RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, symbol.getName(), false).asRNode();
                     }
                 } else if (RRuntime.convertScalarVectors(arg) instanceof RAttributable) {
-                    defaultValue = ConstantNode.create(arg);
+                    defaultValue = RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, arg).asRNode();
                 } else {
                     throw RInternalError.unimplemented();
                 }
@@ -132,10 +131,10 @@ public abstract class AsFunction extends RBuiltinNode.Arg2 {
         if (bodyObject instanceof RLanguage) {
             body = ((RLanguage) x.getDataAtAsObject(x.getLength() - 1)).getRep();
         } else if (bodyObject instanceof RSymbol) {
-            body = ReadVariableNode.create(((RSymbol) bodyObject).getName());
+            body = RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, ((RSymbol) bodyObject).getName(), false).asRNode();
         } else {
             assert bodyObject instanceof Integer || bodyObject instanceof Double || bodyObject instanceof Byte || bodyObject instanceof String;
-            body = ConstantNode.create(bodyObject);
+            body = RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, bodyObject).asRNode();
         }
         if (!RBaseNode.isRSyntaxNode(body)) {
             throw RInternalError.unimplemented();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java
index 4dd7c7c25de24671ae13ade5df754a09c4a1e1b4..c6f72e666cc5aa71de98f9c01a976e4a79c810e1 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java
@@ -81,7 +81,7 @@ public abstract class Call extends RBuiltinNode.Arg2 {
 
         @TruffleBoundary
         private RLanguage makeCall(String name, RArgsValuesAndNames args) {
-            return "function".equals(name) ? makeFunction(args) : makeCall0(ReadVariableNode.createFunctionLookup(RSyntaxNode.LAZY_DEPARSE, name), false, args);
+            return "function".equals(name) ? makeFunction(args) : makeCall0(ReadVariableNode.wrap(RSyntaxNode.LAZY_DEPARSE, ReadVariableNode.createFunctionLookup(name)), false, args);
         }
 
         private RLanguage makeFunction(RArgsValuesAndNames args) {
@@ -108,7 +108,7 @@ public abstract class Call extends RBuiltinNode.Arg2 {
 
         @TruffleBoundary
         protected RLanguage makeCallSourceUnavailable(String name, RArgsValuesAndNames args) {
-            return "function".equals(name) ? makeFunction(args) : makeCall0(ReadVariableNode.createFunctionLookup(RSyntaxNode.LAZY_DEPARSE, name), true, args);
+            return "function".equals(name) ? makeFunction(args) : makeCall0(ReadVariableNode.wrap(RSyntaxNode.LAZY_DEPARSE, ReadVariableNode.createFunctionLookup(name)), true, args);
         }
 
         @TruffleBoundary
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java
index b9cc5811661cdbfc597b6b5e5208ba8f4ec7d4c8..271e4ac0bd5980f0966e60189d3f043000dab43e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java
@@ -44,7 +44,6 @@ import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.RASTUtils;
 import com.oracle.truffle.r.nodes.access.ConstantNode;
-import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.DoCallNodeGen.DoCallInternalNodeGen;
@@ -235,7 +234,7 @@ public abstract class DoCall extends RBuiltinNode.Arg4 implements InternalRSynta
                     if (symbol.isMissing()) {
                         argsConstants[i] = ConstantNode.create(REmpty.instance);
                     } else {
-                        argsConstants[i] = ReadVariableNode.create(((RSymbol) argValues[i]).getName());
+                        argsConstants[i] = RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, ((RSymbol) argValues[i]).getName(), false);
                     }
                 } else {
                     argsConstants[i] = ConstantNode.create(argValues[i]);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java
index 2d1bf4615b76927fc598fb5aa050ef44322c3f73..a6e10e9ec1e2dca9b7b13a612b0706f55c51be26 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java
@@ -44,7 +44,6 @@ import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.RASTUtils;
 import com.oracle.truffle.r.nodes.RRootNode;
 import com.oracle.truffle.r.nodes.access.ConstantNode;
-import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.FrameFunctionsFactory.SysFrameNodeGen;
 import com.oracle.truffle.r.nodes.function.ArgumentMatcher;
@@ -351,7 +350,7 @@ public class FrameFunctions {
                 Object argument = varArgParameter.getArgument(((VarArgNode) arg).getIndex());
                 if (argument instanceof RPromise) {
                     RNode unwrapped = (RNode) RASTUtils.unwrap(((RPromise) argument).getRep());
-                    return unwrapped instanceof ConstantNode ? unwrapped : ReadVariableNode.create(createVarArgName((VarArgNode) arg));
+                    return unwrapped instanceof ConstantNode ? unwrapped : RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, createVarArgName((VarArgNode) arg), false).asRNode();
                 } else {
                     return ConstantNode.create(argument);
                 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java
index 0e8c9f0639a7a21082dbdba6dcedeabae9d49cc4..1065e130eebf54c35729bf8c50d3bb8fe64f6030 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java
@@ -36,6 +36,7 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNames
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.LapplyNodeGen.LapplyInternalNodeGen;
 import com.oracle.truffle.r.nodes.control.RLengthNode;
+import com.oracle.truffle.r.nodes.function.RCallBaseNode;
 import com.oracle.truffle.r.nodes.function.RCallNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RError;
@@ -44,12 +45,14 @@ import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RSource;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 import com.oracle.truffle.r.runtime.nodes.InternalRSyntaxNodeChildren;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
+import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxCall;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxElement;
@@ -152,8 +155,8 @@ public abstract class Lapply extends RBuiltinNode.Arg2 {
                         @Cached("createVectorSlot(frame)") FrameSlot vectorSlot,
                         @Cached("create()") RLengthNode lengthNode,
                         @Cached("createCountingProfile()") LoopConditionProfile loop,
-                        @Cached("createCallNode(vectorSlot, indexSlot)") RCallNode firstCallNode,
-                        @Cached("createCallNode(vectorSlot, indexSlot)") RCallNode callNode) {
+                        @Cached("createCallNode(vectorSlot, indexSlot)") RCallBaseNode firstCallNode,
+                        @Cached("createCallNode(vectorSlot, indexSlot)") RCallBaseNode callNode) {
             // TODO: R switches to double if x.getLength() is greater than 2^31-1
             FrameSlotChangeMonitor.setObject(frame, vectorSlot, vector);
             int length = lengthNode.executeInteger(frame, vector);
@@ -174,13 +177,14 @@ public abstract class Lapply extends RBuiltinNode.Arg2 {
         /**
          * Creates the {@link RCallNode} for this target and {@code varArgs}.
          */
-        protected RCallNode createCallNode(FrameSlot vectorSlot, FrameSlot indexSlot) {
+        protected RCallBaseNode createCallNode(FrameSlot vectorSlot, FrameSlot indexSlot) {
             CompilerAsserts.neverPartOfCompilation();
 
             ExtractElementInternal element = new ExtractElementInternal(vectorSlot, indexSlot);
-            ReadVariableNode readArgs = ReadVariableNode.createSilent(ArgumentsSignature.VARARG_NAME, RType.Any);
+            RSyntaxNode readArgs = ReadVariableNode.wrap(RSyntaxNode.LAZY_DEPARSE, ReadVariableNode.createSilent(ArgumentsSignature.VARARG_NAME, RType.Any));
+            RNode function = RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, "FUN", false).asRNode();
 
-            return RCallNode.createCall(createCallSourceSection(), ReadVariableNode.create("FUN"), ArgumentsSignature.get(null, "..."), element, readArgs);
+            return RCallNode.createCall(createCallSourceSection(), function, ArgumentsSignature.get(null, "..."), element, readArgs);
         }
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
index 8ffd0ed1d7dae9918eda5d443c2bb0b19f9a1434..76a3262d6c8acc9341648387b34c9e3565c8d35d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
@@ -37,18 +37,19 @@ import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.access.WriteVariableNode;
 import com.oracle.truffle.r.nodes.access.WriteVariableNode.Mode;
-import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode;
 import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.MapplyNodeGen.MapplyInternalNodeGen;
 import com.oracle.truffle.r.nodes.control.RLengthNode;
+import com.oracle.truffle.r.nodes.function.RCallBaseNode;
 import com.oracle.truffle.r.nodes.function.RCallNode;
 import com.oracle.truffle.r.nodes.function.call.RExplicitCallNode;
 import com.oracle.truffle.r.runtime.AnonymousFrameVariable;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RFunction;
@@ -139,7 +140,7 @@ public abstract class Mapply extends RBuiltinNode.Arg3 {
                         @SuppressWarnings("unused") @Cached(value = "extractNames(dots)", dimensions = 1) String[] cachedDotsNames,
                         @SuppressWarnings("unused") @Cached(value = "extractNames(moreArgs)", dimensions = 1) String[] cachedMoreArgsNames,
                         @Cached("createElementNodeArray(dotsLength, moreArgsLength, cachedDotsNames, cachedMoreArgsNames)") ElementNode[] cachedElementNodeArray,
-                        @Cached("createCallNode(cachedElementNodeArray)") RCallNode callNode) {
+                        @Cached("createCallNode(cachedElementNodeArray)") RCallBaseNode callNode) {
             int[] lengths = new int[dotsLength];
             int maxLength = getDotsLengths(frame, dots, dotsLength, cachedElementNodeArray, lengths);
             storeAdditionalArguments(frame, moreArgs, dotsLength, moreArgsLength, cachedElementNodeArray);
@@ -234,12 +235,12 @@ public abstract class Mapply extends RBuiltinNode.Arg3 {
         /**
          * Creates the {@link RCallNode} for this target.
          */
-        protected RCallNode createCallNode(ElementNode[] elementNodeArray) {
+        protected RCallBaseNode createCallNode(ElementNode[] elementNodeArray) {
             CompilerAsserts.neverPartOfCompilation();
             RSyntaxNode[] syntaxNodes = new RSyntaxNode[elementNodeArray.length];
             String[] names = new String[elementNodeArray.length];
             for (int i = 0; i < syntaxNodes.length; i++) {
-                syntaxNodes[i] = ReadVariableNode.create(elementNodeArray[i].vectorElementName).asRSyntaxNode();
+                syntaxNodes[i] = RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, elementNodeArray[i].vectorElementName, false);
                 names[i] = elementNodeArray[i].argName;
             }
             // Errors can be thrown from the modified call so a SourceSection is required
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatchFun.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatchFun.java
index 4c7fbdd5c92e774fcb1bf1e897040e332606f1d9..149dcdb68df06499c12812db715ae17b15e5fb00 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatchFun.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatchFun.java
@@ -104,7 +104,7 @@ public abstract class MatchFun extends RBuiltinNode.Arg2 {
         }
 
         protected static ReadVariableNode createLookup(String name, boolean descend) {
-            return descend ? ReadVariableNode.createFunctionLookup(RSyntaxNode.INTERNAL, name) : ReadVariableNode.create(RSyntaxNode.INTERNAL, name, false);
+            return descend ? ReadVariableNode.createFunctionLookup(name) : ReadVariableNode.create(name);
         }
 
         protected static String firstString(RAbstractStringVector vec) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java
index 98c7e6420098a0b05fac67463bd3adf6275a0cf2..52efddcdd4fbd4c2a2eda5c01ba82ab1a0bf23ce 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java
@@ -23,7 +23,6 @@ import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.access.AccessSlotNode;
 import com.oracle.truffle.r.nodes.access.AccessSlotNodeGen;
 import com.oracle.truffle.r.nodes.access.ConstantNode;
-import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.function.WrapArgumentNode;
 import com.oracle.truffle.r.nodes.function.opt.UpdateShareableChildValueNode;
@@ -32,6 +31,7 @@ import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RSymbol;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
 
 @RBuiltin(name = "@", kind = PRIMITIVE, parameterNames = {"", ""}, nonEvalArgs = 1, behavior = COMPLEX)
 public abstract class Slot extends RBuiltinNode.Arg2 {
@@ -58,8 +58,8 @@ public abstract class Slot extends RBuiltinNode.Arg2 {
                 if (val instanceof RSymbol) {
                     return ((RSymbol) val).getName();
                 }
-            } else if (rep instanceof ReadVariableNode) {
-                return ((ReadVariableNode) rep).getIdentifier();
+            } else if (rep instanceof RSyntaxLookup) {
+                return ((RSyntaxLookup) rep).getIdentifier();
             }
         }
         CompilerDirectives.transferToInterpreter();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSlot.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSlot.java
index 083a7bcbe272cfe059e3f61900662e65c0c086fc..135fea29b3990a92cf73aa9ca525e24c8f2eb8b0 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSlot.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSlot.java
@@ -42,7 +42,6 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxElement;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
-import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 @RBuiltin(name = "@<-", kind = PRIMITIVE, parameterNames = {"", "", "value"}, nonEvalArgs = 1, behavior = COMPLEX)
 public abstract class UpdateSlot extends RBuiltinNode.Arg3 {
@@ -79,7 +78,7 @@ public abstract class UpdateSlot extends RBuiltinNode.Arg3 {
         @CompilationFinal private RFunction checkSlotAssignFunction;
         @Child private ClassHierarchyNode objClassHierarchy;
         @Child private ClassHierarchyNode valClassHierarchy;
-        @Child private ReadVariableNode checkAtAssignmentFind = ReadVariableNode.createFunctionLookup(RSyntaxNode.INTERNAL, "checkAtAssignment");
+        @Child private ReadVariableNode checkAtAssignmentFind = ReadVariableNode.createFunctionLookup("checkAtAssignment");
         @Child private CallRFunctionNode checkAtAssignmentCall;
 
         private final ConditionProfile cached = ConditionProfile.createBinaryProfile();
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java
index 81ac86b1813f933a3ad39dda3e7fc49b7673fce7..c5bb93fb1c4a8aeb62881a31f395c3c631a7df23 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java
@@ -54,6 +54,7 @@ import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.FastROptions;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.FastPathFactory;
+import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.context.TruffleRLanguage;
 import com.oracle.truffle.r.runtime.data.REmpty;
 import com.oracle.truffle.r.runtime.data.RShareable;
@@ -115,9 +116,9 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> {
                         boolean switchArgs = "->".equals(symbol) || "->>".equals(symbol);
                         // fix the operators while keeping the correct source sections
                         if ("->>".equals(symbol)) {
-                            lhsLookup = ReadVariableNode.createForcedFunctionLookup(lhs.getLazySourceSection(), "<<-");
+                            lhsLookup = (RSyntaxLookup) ReadVariableNode.wrap(lhs.getLazySourceSection(), ReadVariableNode.createForcedFunctionLookup("<<-"));
                         } else if ("->".equals(symbol)) {
-                            lhsLookup = ReadVariableNode.createForcedFunctionLookup(lhs.getLazySourceSection(), "<-");
+                            lhsLookup = (RSyntaxLookup) ReadVariableNode.wrap(lhs.getLazySourceSection(), ReadVariableNode.createForcedFunctionLookup("<-"));
                         }
                         // switch the args if needed
                         RSyntaxNode lhsArg = args.get(switchArgs ? 1 : 0).value;
@@ -289,6 +290,6 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> {
                 return new ReadVariadicComponentNode(source, index > 0 ? index - 1 : index);
             }
         }
-        return functionLookup ? ReadVariableNode.createForcedFunctionLookup(source, symbol) : ReadVariableNode.create(source, symbol, false);
+        return ReadVariableNode.wrap(source, functionLookup ? ReadVariableNode.createForcedFunctionLookup(symbol) : ReadVariableNode.create(symbol));
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
index 2cf94eb5e65c710d78700f9b18a3bdf91fb5b0d8..5d556ba0bbbeda8b73eb0074c65075ebdc423497 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
@@ -38,7 +38,6 @@ import com.oracle.truffle.r.nodes.function.RCallSpecialNode;
 import com.oracle.truffle.r.nodes.function.WrapArgumentBaseNode;
 import com.oracle.truffle.r.nodes.function.WrapArgumentNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
-import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -223,22 +222,4 @@ public final class RASTUtils {
         SourceSection sourceSection = sourceUnavailable ? RSyntaxNode.SOURCE_UNAVAILABLE : RSyntaxNode.LAZY_DEPARSE;
         return RCallSpecialNode.createCall(sourceSection, fnNode, signature, arguments);
     }
-
-    @TruffleBoundary
-    public static String expectName(RNode node) {
-        if (node instanceof ConstantNode) {
-            Object c = ((ConstantNode) node).getValue();
-            if (c instanceof String) {
-                return (String) c;
-            } else if (c instanceof Double) {
-                return ((Double) c).toString();
-            } else {
-                throw RInternalError.unimplemented();
-            }
-        } else if (node instanceof ReadVariableNode) {
-            return ((ReadVariableNode) node).getIdentifier();
-        } else {
-            throw RInternalError.unimplemented();
-        }
-    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java
index 535ed30b70b737426d63326036b21181d04570f5..edc1696e2cbfa1435934e7b172844622627121ea 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java
@@ -32,7 +32,6 @@ import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.NodeCost;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.RASTUtils;
-import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinRootNode;
 import com.oracle.truffle.r.nodes.function.ArgumentStatePush;
 import com.oracle.truffle.r.nodes.function.FormalArguments;
@@ -49,6 +48,7 @@ import com.oracle.truffle.r.runtime.data.RPromise.Closure;
 import com.oracle.truffle.r.runtime.data.RPromise.PromiseState;
 import com.oracle.truffle.r.runtime.data.RPromise.RPromiseFactory;
 import com.oracle.truffle.r.runtime.nodes.RNode;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
 
 /**
  * This {@link RNode} returns a function's argument specified by its formal index. It is used to
@@ -156,7 +156,7 @@ public final class AccessArgumentNode extends RNode {
 
             // TODO: all tests pass without it but perhaps we should "re-wrap" promises here?
             if (isOptimizableDefault(arg)) {
-                optDefaultArgNode = new OptVariableDefaultPromiseNode(factory, (ReadVariableNode) RASTUtils.cloneNode(arg), ArgumentStatePush.INVALID_INDEX);
+                optDefaultArgNode = new OptVariableDefaultPromiseNode(factory, (RSyntaxLookup) arg.asRSyntaxNode(), ArgumentStatePush.INVALID_INDEX);
             } else {
                 Object optimizableConstant = getOptimizableConstant(arg);
                 if (optimizableConstant != null) {
@@ -174,8 +174,8 @@ public final class AccessArgumentNode extends RNode {
 
     private final class OptVariableDefaultPromiseNode extends OptVariablePromiseBaseNode {
 
-        OptVariableDefaultPromiseNode(RPromiseFactory factory, ReadVariableNode rvn, int wrapIndex) {
-            super(factory, rvn, wrapIndex);
+        OptVariableDefaultPromiseNode(RPromiseFactory factory, RSyntaxLookup lookup, int wrapIndex) {
+            super(factory, lookup, wrapIndex);
         }
 
         @Override
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 19334b09e2066a604b4023ff6051b5c155075d2e..809ee9face9979c4f155c1da2e4172ea185a92a4 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
@@ -31,12 +31,14 @@ import com.oracle.truffle.api.frame.FrameSlotKind;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.InvalidAssumptionException;
 import com.oracle.truffle.api.nodes.Node;
+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.runtime.RError;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RPromise;
+import com.oracle.truffle.r.runtime.data.RTypesGen;
 import com.oracle.truffle.r.runtime.env.frame.ActiveBinding;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 
@@ -136,4 +138,16 @@ public final class LocalReadVariableNode extends Node {
         }
         return result;
     }
+
+    public int executeInteger(VirtualFrame frame) throws UnexpectedResultException {
+        return RTypesGen.expectInteger(execute(frame));
+    }
+
+    public double executeDouble(VirtualFrame frame) throws UnexpectedResultException {
+        return RTypesGen.expectDouble(execute(frame));
+    }
+
+    public byte executeByte(VirtualFrame frame) throws UnexpectedResultException {
+        return RTypesGen.expectByte(execute(frame));
+    }
 }
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 24665dff03a2b1c52d1bc4fe937a543a3fcc34d8..09fd6d12808e666d27883d4fcec18bf34c28edd5 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
@@ -80,12 +80,53 @@ import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
+final class LookupNode extends RSourceSectionNode implements RSyntaxNode, RSyntaxLookup {
+
+    @Child private ReadVariableNode read;
+    @Child private SetVisibilityNode visibility;
+
+    LookupNode(SourceSection sourceSection, ReadVariableNode read) {
+        super(sourceSection);
+        this.read = read;
+    }
+
+    @Override
+    public void voidExecute(VirtualFrame frame) {
+        read.executeInternal(frame, frame);
+    }
+
+    @Override
+    public Object execute(VirtualFrame frame) {
+        return read.executeInternal(frame, frame);
+    }
+
+    @Override
+    public Object visibleExecute(VirtualFrame frame) {
+        if (visibility == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            visibility = insert(SetVisibilityNode.create());
+        }
+        visibility.execute(frame, true);
+        return read.executeInternal(frame, frame);
+    }
+
+    @Override
+    public String getIdentifier() {
+        return read.getIdentifier();
+    }
+
+    @Override
+    public boolean isFunctionLookup() {
+        return read.isFunctionLookup();
+    }
+}
+
 /**
  * This node is used to read a variable from the local or enclosing environments. It specializes to
  * a particular layout of frame descriptors and enclosing environments, and re-specializes in case
  * the layout changes.
  */
-public final class ReadVariableNode extends RSourceSectionNode implements RSyntaxNode, RSyntaxLookup {
+public final class ReadVariableNode extends RBaseNode {
 
     private static final int MAX_INVALIDATION_COUNT = 8;
 
@@ -105,36 +146,39 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta
     }
 
     public static ReadVariableNode create(String name) {
-        return new ReadVariableNode(RSyntaxNode.SOURCE_UNAVAILABLE, name, RType.Any, ReadKind.Normal);
+        return new ReadVariableNode(name, RType.Any, ReadKind.Normal);
     }
 
-    public static ReadVariableNode create(SourceSection src, String name, boolean shouldCopyValue) {
-        return new ReadVariableNode(src, name, RType.Any, shouldCopyValue ? ReadKind.Copying : ReadKind.Normal);
+    public static ReadVariableNode create(String name, boolean shouldCopyValue) {
+        return new ReadVariableNode(name, RType.Any, shouldCopyValue ? ReadKind.Copying : ReadKind.Normal);
     }
 
     public static ReadVariableNode createSilent(String name, RType mode) {
-        return new ReadVariableNode(RSyntaxNode.SOURCE_UNAVAILABLE, name, mode, ReadKind.Silent);
+        return new ReadVariableNode(name, mode, ReadKind.Silent);
     }
 
     public static ReadVariableNode createSilentMissing(String name, RType mode) {
-        return new ReadVariableNode(RSyntaxNode.SOURCE_UNAVAILABLE, name, mode, ReadKind.SilentMissing);
+        return new ReadVariableNode(name, mode, ReadKind.SilentMissing);
     }
 
-    public static ReadVariableNode createSuperLookup(SourceSection src, String name) {
-        return new ReadVariableNode(src, name, RType.Any, ReadKind.Super);
+    public static ReadVariableNode createSuperLookup(String name) {
+        return new ReadVariableNode(name, RType.Any, ReadKind.Super);
     }
 
-    public static ReadVariableNode createFunctionLookup(SourceSection src, String identifier) {
-        return new ReadVariableNode(src, identifier, RType.Function, ReadKind.Normal);
+    public static ReadVariableNode createFunctionLookup(String identifier) {
+        return new ReadVariableNode(identifier, RType.Function, ReadKind.Normal);
     }
 
-    public static ReadVariableNode createForcedFunctionLookup(SourceSection src, String name) {
-        return new ReadVariableNode(src, name, RType.Function, ReadKind.ForcedTypeCheck);
+    public static ReadVariableNode createForcedFunctionLookup(String name) {
+        return new ReadVariableNode(name, RType.Function, ReadKind.ForcedTypeCheck);
+    }
+
+    public static RSyntaxNode wrap(SourceSection sourceSection, ReadVariableNode read) {
+        return new LookupNode(sourceSection, read);
     }
 
     @Child private PromiseHelperNode promiseHelper;
     @Child private CheckTypeNode checkTypeNode;
-    @Child private SetVisibilityNode visibility;
 
     @CompilationFinal private FrameLevel read;
     @CompilationFinal private boolean needsCopying;
@@ -153,8 +197,7 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta
 
     @CompilationFinal(dimensions = 1) private final boolean[] seenValueKinds = new boolean[FrameSlotKind.values().length];
 
-    private ReadVariableNode(SourceSection sourceSection, Object identifier, RType mode, ReadKind kind) {
-        super(sourceSection);
+    private ReadVariableNode(Object identifier, RType mode, ReadKind kind) {
         this.identifier = identifier;
         this.identifierAsString = identifier.toString().intern();
         this.mode = mode;
@@ -163,7 +206,6 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta
         this.copyProfile = kind != ReadKind.Copying ? null : ConditionProfile.createBinaryProfile();
     }
 
-    @Override
     public String getIdentifier() {
         return identifierAsString;
     }
@@ -172,38 +214,16 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta
         return mode;
     }
 
-    @Override
-    public boolean isSyntax() {
-        return identifier instanceof String;
-    }
-
-    @Override
-    public void voidExecute(VirtualFrame frame) {
-        executeInternal(frame, frame);
-    }
-
-    @Override
     public Object execute(VirtualFrame frame) {
         return executeInternal(frame, frame);
     }
 
-    @Override
-    public Object visibleExecute(VirtualFrame frame) {
-        assert kind != ReadKind.Silent;
-        if (visibility == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            visibility = insert(SetVisibilityNode.create());
-        }
-        visibility.execute(frame, true);
-        return executeInternal(frame, frame);
-    }
-
     public Object execute(VirtualFrame frame, Frame variableFrame) {
         assert frame != null;
         return executeInternal(frame, variableFrame);
     }
 
-    private Object executeInternal(VirtualFrame frame, Frame initialFrame) {
+    Object executeInternal(VirtualFrame frame, Frame initialFrame) {
         Frame variableFrame = kind == ReadKind.Super ? superEnclosingFrameProfile.profile(RArguments.getEnclosingFrame(initialFrame)) : initialFrame;
 
         Object result;
@@ -943,7 +963,6 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta
         return kind == ReadKind.ForcedTypeCheck;
     }
 
-    @Override
     public boolean isFunctionLookup() {
         return mode == RType.Function;
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java
index 723c904d36c930ecd77fc9e46a180d3ca4d6d7a8..fb725d99fb0ab525cdc9007070c40413610b2aba 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/AbstractLoopNode.java
@@ -22,9 +22,13 @@
  */
 package com.oracle.truffle.r.nodes.control;
 
+import com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.nodes.RepeatingNode;
 import com.oracle.truffle.api.nodes.RootNode;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.r.nodes.RRootNode;
+import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxCall;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxElement;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
@@ -52,4 +56,25 @@ public abstract class AbstractLoopNode extends OperatorNode {
         String name = ((RSyntaxLookup) call).getIdentifier();
         return String.format("%s-<%s:%d>", name, function, startLine);
     }
+
+    protected static abstract class AbstractRepeatingNode extends Node implements RepeatingNode {
+
+        @Child protected RNode body;
+
+        public AbstractRepeatingNode(RNode body) {
+            this.body = body;
+        }
+    }
+
+    /**
+     * Tests if the provided node is a loop-body node (also considering wrappers).
+     */
+    public static boolean isLoopBody(Node n) {
+        Node parent = n.getParent();
+        if (parent instanceof WrapperNode) {
+            Node grandparent = parent.getParent();
+            return grandparent instanceof AbstractRepeatingNode && ((AbstractRepeatingNode) grandparent).body == parent;
+        }
+        return parent instanceof AbstractRepeatingNode && ((AbstractRepeatingNode) parent).body == n;
+    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java
index 1dff7905d99db47962aa51e6c4e8dbc1512ec109..a0270602462d3676a5c35afd7f274a552f036e35 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java
@@ -22,22 +22,21 @@
  */
 package com.oracle.truffle.r.nodes.control;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.frame.VirtualFrame;
-import com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode;
 import com.oracle.truffle.api.nodes.LoopNode;
-import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.api.nodes.RepeatingNode;
 import com.oracle.truffle.api.nodes.UnexpectedResultException;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.r.nodes.access.WriteVariableNode;
 import com.oracle.truffle.r.nodes.access.WriteVariableNode.Mode;
-import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
+import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode;
 import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
 import com.oracle.truffle.r.runtime.AnonymousFrameVariable;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
+import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.nodes.RCodeBuilder;
@@ -49,11 +48,13 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyntaxCall {
 
+    @Child private RNode range;
+    @Child private RLengthNode length;
     @Child private WriteVariableNode writeLengthNode;
     @Child private WriteVariableNode writeIndexNode;
     @Child private WriteVariableNode writeRangeNode;
     @Child private LoopNode loopNode;
-    @Child private SetVisibilityNode visibility = SetVisibilityNode.create();
+    @Child private SetVisibilityNode visibility;
 
     private final RSyntaxLookup var;
 
@@ -64,45 +65,62 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn
         String rangeName = AnonymousFrameVariable.create("FOR_RANGE");
         String lengthName = AnonymousFrameVariable.create("FOR_LENGTH");
 
+        this.range = range;
+        this.length = RLengthNodeGen.create();
         this.writeIndexNode = WriteVariableNode.createAnonymous(indexName, Mode.REGULAR, null);
-        this.writeRangeNode = WriteVariableNode.createAnonymous(rangeName, Mode.REGULAR, range);
-        this.writeLengthNode = WriteVariableNode.createAnonymous(lengthName, Mode.REGULAR, RLengthNodeGen.create(ReadVariableNode.create(rangeName)));
+        this.writeRangeNode = WriteVariableNode.createAnonymous(rangeName, Mode.REGULAR, null);
+        this.writeLengthNode = WriteVariableNode.createAnonymous(lengthName, Mode.REGULAR, null);
         this.loopNode = Truffle.getRuntime().createLoopNode(new ForRepeatingNode(this, var.getIdentifier(), body, indexName, lengthName, rangeName));
     }
 
     @Override
-    public Object execute(VirtualFrame frame) {
+    public void voidExecute(VirtualFrame frame) {
+        Object obj = range.execute(frame);
         writeIndexNode.execute(frame, 1);
-        writeRangeNode.execute(frame);
-        writeLengthNode.execute(frame);
+        writeRangeNode.execute(frame, obj);
+        writeLengthNode.execute(frame, length.executeInteger(frame, obj));
         loopNode.executeLoop(frame);
+    }
+
+    @Override
+    public Object execute(VirtualFrame frame) {
+        voidExecute(frame);
+        return RNull.instance;
+    }
+
+    @Override
+    public Object visibleExecute(VirtualFrame frame) {
+        voidExecute(frame);
+        if (visibility == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            visibility = insert(SetVisibilityNode.create());
+        }
         visibility.execute(frame, false);
         return RNull.instance;
     }
 
-    private static final class ForRepeatingNode extends Node implements RepeatingNode {
+    private static final class ForRepeatingNode extends AbstractRepeatingNode {
 
         private final ConditionProfile conditionProfile = ConditionProfile.createCountingProfile();
         private final BranchProfile breakBlock = BranchProfile.create();
         private final BranchProfile nextBlock = BranchProfile.create();
 
         @Child private WriteVariableNode writeElementNode;
-        @Child private RNode body;
 
-        @Child private ReadVariableNode readIndexNode;
-        @Child private ReadVariableNode readLengthNode;
+        @Child private LocalReadVariableNode readIndexNode;
+        @Child private LocalReadVariableNode readLengthNode;
         @Child private WriteVariableNode writeIndexNode;
 
         // only used for toString
         private final ForNode forNode;
 
         ForRepeatingNode(ForNode forNode, String var, RNode body, String indexName, String lengthName, String rangeName) {
+            super(body);
             this.forNode = forNode;
             this.writeElementNode = WriteVariableNode.createAnonymous(var, Mode.REGULAR, createIndexedLoad(indexName, rangeName), false);
-            this.body = body;
 
-            this.readIndexNode = ReadVariableNode.create(indexName);
-            this.readLengthNode = ReadVariableNode.create(lengthName);
+            this.readIndexNode = LocalReadVariableNode.create(indexName, true);
+            this.readLengthNode = LocalReadVariableNode.create(lengthName, true);
             this.writeIndexNode = WriteVariableNode.createAnonymous(indexName, Mode.REGULAR, null);
             // pre-initialize the profile so that loop exits to not deoptimize
             conditionProfile.profile(false);
@@ -124,7 +142,7 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn
                 length = readLengthNode.executeInteger(frame);
                 index = readIndexNode.executeInteger(frame);
             } catch (UnexpectedResultException e1) {
-                throw new AssertionError("For index must be Integer.");
+                throw RInternalError.shouldNotReachHere("For index must be Integer.");
             }
             try {
                 if (conditionProfile.profile(index <= length)) {
@@ -154,23 +172,11 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn
     @Override
     public RSyntaxElement[] getSyntaxArguments() {
         ForRepeatingNode repeatingNode = (ForRepeatingNode) loopNode.getRepeatingNode();
-        return new RSyntaxElement[]{var, writeRangeNode.getRhs().asRSyntaxNode(), repeatingNode.body.asRSyntaxNode()};
+        return new RSyntaxElement[]{var, range.asRSyntaxNode(), repeatingNode.body.asRSyntaxNode()};
     }
 
     @Override
     public ArgumentsSignature getSyntaxSignature() {
         return ArgumentsSignature.empty(3);
     }
-
-    /**
-     * Tests if the provided node is a loop-body node (also considering wrappers).
-     */
-    public static boolean isLoopBody(Node n) {
-        Node parent = n.getParent();
-        if (parent instanceof WrapperNode) {
-            Node grandparent = parent.getParent();
-            return grandparent instanceof ForRepeatingNode && ((ForRepeatingNode) grandparent).body == parent;
-        }
-        return parent instanceof ForRepeatingNode && ((ForRepeatingNode) parent).body == n;
-    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/RepeatNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/RepeatNode.java
index 0e489ec557ee45c7f65efc2671a0b534e2b37ef4..e29f22a7c8cfbe17721c44f97193e1e150166508 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/RepeatNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/RepeatNode.java
@@ -25,8 +25,6 @@ package com.oracle.truffle.r.nodes.control;
 import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.LoopNode;
-import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.api.nodes.RepeatingNode;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
@@ -55,9 +53,7 @@ public final class RepeatNode extends AbstractLoopNode implements RSyntaxNode, R
         return RNull.instance;
     }
 
-    private static final class RepeatRepeatingNode extends Node implements RepeatingNode {
-
-        @Child private RNode body;
+    private static final class RepeatRepeatingNode extends AbstractRepeatingNode {
 
         private final BranchProfile normalBlock = BranchProfile.create();
         private final BranchProfile breakBlock = BranchProfile.create();
@@ -67,8 +63,8 @@ public final class RepeatNode extends AbstractLoopNode implements RSyntaxNode, R
         private final RepeatNode whileNode;
 
         RepeatRepeatingNode(RepeatNode whileNode, RNode body) {
+            super(body);
             this.whileNode = whileNode;
-            this.body = body;
         }
 
         @Override
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
index 284ebf3436c1618a1eb5833555b8b75403c78a03..bf28bec6ccf021021efe50b103d1c98c778ad9be 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
@@ -164,11 +164,16 @@ abstract class ReplacementNode extends OperatorNode {
         return null;
     }
 
+    private static RSyntaxNode createLookup(SourceSection source, String idenifier) {
+        return RContext.getASTBuilder().lookup(source, idenifier, false);
+    }
+
     private static RNode createReplacementTarget(RSyntaxLookup variable, boolean isSuper, boolean localPeek) {
         if (isSuper) {
-            return ReadVariableNode.createSuperLookup(variable.getLazySourceSection(), variable.getIdentifier());
+            return ReadVariableNode.wrap(variable.getLazySourceSection(), ReadVariableNode.createSuperLookup(variable.getIdentifier())).asRNode();
         } else {
-            return localPeek ? new PeekLocalVariableNode(variable.getIdentifier()) : ReadVariableNode.create(variable.getLazySourceSection(), variable.getIdentifier(), true);
+            return localPeek ? new PeekLocalVariableNode(variable.getIdentifier())
+                            : ReadVariableNode.wrap(variable.getLazySourceSection(), ReadVariableNode.create(variable.getIdentifier(), true)).asRNode();
         }
     }
 
@@ -253,7 +258,8 @@ abstract class ReplacementNode extends OperatorNode {
                 extractFunc = createSpecialFunctionQuery(calls.get(i), extractFunc.asRSyntaxNode(), codeBuilderContext);
                 ((RCallSpecialNode) extractFunc).setPropagateFullCallNeededException();
             }
-            this.replaceCall = (RCallSpecialNode) createFunctionUpdate(source, extractFunc.asRSyntaxNode(), ReadVariableNode.create(getRHSTemp(tempNamesStartIndex)), calls.get(0), codeBuilderContext);
+            this.replaceCall = (RCallSpecialNode) createFunctionUpdate(source, extractFunc.asRSyntaxNode(), createLookup(RSyntaxNode.INTERNAL, getRHSTemp(tempNamesStartIndex)), calls.get(0),
+                            codeBuilderContext);
             this.replaceCall.setPropagateFullCallNeededException();
         }
 
@@ -377,7 +383,7 @@ abstract class ReplacementNode extends OperatorNode {
              * replacement, 'x' in our example (the assignment from 'x' is not done in this loop).
              */
             for (int i = calls.size() - 1; i >= 1; i--) {
-                ReadVariableNode newFirstArg = ReadVariableNode.create(getTargetTemp(targetIndex));
+                RSyntaxNode newFirstArg = createLookup(RSyntaxNode.INTERNAL, getTargetTemp(targetIndex));
                 RNode extract = createSpecialFunctionQuery(calls.get(i), newFirstArg, codeBuilderContext);
                 instructions.add(WriteVariableNode.createAnonymous(getTargetTemp(++targetIndex), WriteVariableNode.Mode.INVISIBLE, wrapForSlotUpdate(extract, calls.get(i - 1))));
             }
@@ -387,7 +393,8 @@ abstract class ReplacementNode extends OperatorNode {
              */
             int replacementIndex = tempNamesStartIndex;
             for (int i = 0; i < calls.size(); i++) {
-                RNode update = createFunctionUpdate(source, ReadVariableNode.create(getTargetTemp(targetIndex--)), ReadVariableNode.create(getRHSTemp(replacementIndex)), calls.get(i),
+                RNode update = createFunctionUpdate(source, createLookup(RSyntaxNode.INTERNAL, getTargetTemp(targetIndex--)), createLookup(RSyntaxNode.INTERNAL, getRHSTemp(replacementIndex)),
+                                calls.get(i),
                                 codeBuilderContext);
                 if (i < calls.size() - 1) {
                     instructions.add(WriteVariableNode.createAnonymous(getRHSTemp(++replacementIndex), WriteVariableNode.Mode.INVISIBLE, update));
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/WhileNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/WhileNode.java
index fa7f93e7c2221b4021979a7af1b12d64110b038f..98e84c5e61956437f0144286eb04b308d26d9104 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/WhileNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/WhileNode.java
@@ -25,8 +25,6 @@ package com.oracle.truffle.r.nodes.control;
 import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.LoopNode;
-import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.api.nodes.RepeatingNode;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.source.SourceSection;
@@ -58,10 +56,9 @@ public final class WhileNode extends AbstractLoopNode implements RSyntaxNode, RS
         return RNull.instance;
     }
 
-    private static final class WhileRepeatingNode extends Node implements RepeatingNode {
+    private static final class WhileRepeatingNode extends AbstractRepeatingNode {
 
         @Child private ConvertBooleanNode condition;
-        @Child private RNode body;
 
         private final ConditionProfile conditionProfile = ConditionProfile.createCountingProfile();
         private final BranchProfile normalBlock = BranchProfile.create();
@@ -72,9 +69,9 @@ public final class WhileNode extends AbstractLoopNode implements RSyntaxNode, RS
         private final WhileNode whileNode;
 
         WhileRepeatingNode(WhileNode whileNode, ConvertBooleanNode condition, RNode body) {
+            super(body);
             this.whileNode = whileNode;
             this.condition = condition;
-            this.body = body;
             // pre-initialize the profile so that loop exits to not deoptimize
             conditionProfile.profile(false);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java
index b9a935be29b2dcb4587289d73b80f5dfaf5bf351..0cfd341cb4122e7f245011a2c808aa5eb66b000a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java
@@ -48,6 +48,7 @@ import com.oracle.truffle.r.runtime.RDeparse;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.builtins.FastPathFactory;
 import com.oracle.truffle.r.runtime.builtins.RBuiltinDescriptor;
@@ -64,6 +65,8 @@ import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 import com.oracle.truffle.r.runtime.nodes.EvaluatedArgumentsVisitor;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 import com.oracle.truffle.r.runtime.nodes.RNode;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 /**
  * <p>
@@ -473,12 +476,13 @@ public class ArgumentMatcher {
             return node;
         }
         WrapArgumentNode wrapper = (WrapArgumentNode) node;
-        if (!(wrapper.getOperand() instanceof ReadVariableNode)) {
+        RSyntaxNode syntaxNode = wrapper.getOperand().asRSyntaxNode();
+        if (!(syntaxNode instanceof RSyntaxLookup)) {
             return node;
         }
-        ReadVariableNode rvn = (ReadVariableNode) wrapper.getOperand();
-        ReadVariableNode newRvn = ReadVariableNode.createSilentMissing(rvn.getIdentifier(), rvn.getMode());
-        return WrapArgumentNode.create(newRvn, wrapper.getIndex());
+        RSyntaxLookup lookup = (RSyntaxLookup) syntaxNode;
+        ReadVariableNode newRvn = ReadVariableNode.createSilentMissing(lookup.getIdentifier(), lookup.isFunctionLookup() ? RType.Function : RType.Any);
+        return WrapArgumentNode.create(ReadVariableNode.wrap(lookup.getLazySourceSection(), newRvn).asRNode(), wrapper.getIndex());
     }
 
     private static RNode wrapUnmatched(FormalArguments formals, RBuiltinDescriptor builtin, int formalIndex, boolean noOpt) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java
index 878fdce75eb178e544aec58c3e95abfe8982aad1..b2d5ebe471e2af85b928e377576af4bf6ee3c6d8 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java
@@ -120,7 +120,7 @@ public abstract class PromiseNode extends RNode {
                 if (isVararg(expr)) {
                     return expr;
                 } else if (!noOpt && isOptimizableVariable(expr)) {
-                    return new OptVariableSuppliedPromiseNode(factory, (ReadVariableNode) expr, wrapIndex);
+                    return new OptVariableSuppliedPromiseNode(factory, (RSyntaxLookup) expr, wrapIndex);
                 }
             }
             return new PromisedNode(factory);
@@ -175,8 +175,8 @@ public abstract class PromiseNode extends RNode {
      */
     private static final class OptVariableSuppliedPromiseNode extends OptVariablePromiseBaseNode {
 
-        OptVariableSuppliedPromiseNode(RPromiseFactory factory, ReadVariableNode rvn, int wrapIndex) {
-            super(factory, rvn, wrapIndex);
+        OptVariableSuppliedPromiseNode(RPromiseFactory factory, RSyntaxLookup lookup, int wrapIndex) {
+            super(factory, lookup, wrapIndex);
         }
 
         @Override
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 d74469a35924170b770981b7bb0a0ca2a47e0336..b1732b1e1c45ed98026d07c5249d1ef1fa8b0e89 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
@@ -654,7 +654,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
         return root.containsDispatch() || root.needsSplitting();
     }
 
-    private static final class GetTempNode extends RNode {
+    public static final class GetTempNode extends RNode {
 
         private final FrameSlot slot;
         private final RSyntaxNode arg;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallerHelper.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallerHelper.java
index 8fb51170f9cad3819b28b72e310e239459cd4e99..4b1a0f0af8a824d2e17135a6688db029ba97ef4d 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallerHelper.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallerHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -102,7 +102,7 @@ public final class RCallerHelper {
                             index++;
                         }
                     }
-                    Object replacedFunction = function instanceof String ? ReadVariableNode.createFunctionLookup(RSyntaxNode.LAZY_DEPARSE, (String) function) : function;
+                    Object replacedFunction = function instanceof String ? ReadVariableNode.wrap(RSyntaxNode.LAZY_DEPARSE, ReadVariableNode.createFunctionLookup((String) function)) : function;
                     syntaxNode = RASTUtils.createCall(replacedFunction, true, ArgumentsSignature.get(signature), syntaxArguments);
                 }
                 return syntaxNode;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RMissingHelper.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RMissingHelper.java
index 065db4b08840904abb2649c1178a72998df720cb..e6af350bbfe530935fb4065d856d641c303dde02 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RMissingHelper.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RMissingHelper.java
@@ -34,6 +34,8 @@ import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RPromise.EagerPromise;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 /**
  * This class implements the behavior for {@link RMissing} which is needed inside this module, as it
@@ -113,19 +115,11 @@ public class RMissingHelper {
             return false;
         }
         boolean result = false;
-        Object exprObj = promise.getRep();
-
-        // Unfold WrapArgumentNode
-        if (exprObj instanceof WrapArgumentNode) {
-            exprObj = ((WrapArgumentNode) exprObj).getOperand();
-        }
-        if (exprObj instanceof WrapDefaultArgumentNode) {
-            exprObj = ((WrapDefaultArgumentNode) exprObj).getOperand();
-        }
+        RSyntaxNode syntaxNode = promise.getRep().asRSyntaxNode();
 
         // Check for ReadVariableNode
-        if (exprObj instanceof ReadVariableNode) {
-            ReadVariableNode rvn = (ReadVariableNode) exprObj;
+        if (syntaxNode instanceof RSyntaxLookup) {
+            RSyntaxLookup lookup = (RSyntaxLookup) syntaxNode;
 
             // Check: If there is a cycle, return true. (This is done like in GNU R)
             if (promise.isUnderEvaluation()) {
@@ -150,7 +144,7 @@ public class RMissingHelper {
                     }
                 }
                 // promise.materialize(globalMissingPromiseProfile);
-                result = isMissingArgument(promise.getFrame(), rvn.getIdentifier());
+                result = isMissingArgument(promise.getFrame(), lookup.getIdentifier());
             } finally {
                 promise.resetUnderEvaluation();
             }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/EagerEvalHelper.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/EagerEvalHelper.java
index 099473eb05df4d30f7a9b8da425f901d290e21eb..78f7cc119ef578547f945439ed0490200339bad1 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/EagerEvalHelper.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/EagerEvalHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -26,6 +26,7 @@ import com.oracle.truffle.r.nodes.access.AccessArgumentNode;
 import com.oracle.truffle.r.nodes.access.ConstantNode;
 import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.function.PromiseNode;
+import com.oracle.truffle.r.nodes.function.RCallNode.GetTempNode;
 import com.oracle.truffle.r.runtime.FastROptions;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
@@ -34,6 +35,7 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxCall;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxElement;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 /**
  * Provides small helper function for eager evaluation of arguments for the use in
@@ -81,8 +83,9 @@ public class EagerEvalHelper {
         if (!optConsts()) {
             return null;
         }
-        if (expr instanceof RSyntaxCall) {
-            RSyntaxCall call = (RSyntaxCall) expr;
+        RSyntaxNode syntax = expr.asRSyntaxNode();
+        if (syntax instanceof RSyntaxCall) {
+            RSyntaxCall call = (RSyntaxCall) syntax;
             if (call.getSyntaxLHS() instanceof RSyntaxLookup) {
                 String functionName = ((RSyntaxLookup) call.getSyntaxLHS()).getIdentifier();
                 switch (functionName) {
@@ -99,8 +102,8 @@ public class EagerEvalHelper {
                         break;
                 }
             }
-        } else if (expr instanceof RSyntaxConstant) {
-            return ((RSyntaxConstant) expr).getValue();
+        } else if (syntax instanceof RSyntaxConstant) {
+            return ((RSyntaxConstant) syntax).getValue();
         }
         return null;
     }
@@ -124,7 +127,7 @@ public class EagerEvalHelper {
     private static boolean isVariableArgument(RBaseNode expr) {
         // Do NOT try to optimize anything that might force a Promise, as this might be arbitrary
         // complex (time and space)!
-        return expr instanceof ReadVariableNode && !((ReadVariableNode) expr).isForceForTypeCheck();
+        return !(expr instanceof GetTempNode) && expr.asRSyntaxNode() instanceof RSyntaxLookup && !((RSyntaxLookup) expr.asRSyntaxNode()).isFunctionLookup();
     }
 
     private static boolean isCheapExpressionArgument(@SuppressWarnings("unused") RNode expr) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/OptVariablePromiseBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/OptVariablePromiseBaseNode.java
index 4ee9992eb12985114fe8ddfc4d84b0cf20883ea5..ef9229e20adc23db8633d5d5e3a12fc87dab69be 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/OptVariablePromiseBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/OptVariablePromiseBaseNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -30,39 +30,38 @@ import com.oracle.truffle.api.nodes.InvalidAssumptionException;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.access.FrameSlotNode;
 import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode;
-import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.function.PromiseNode;
 import com.oracle.truffle.r.runtime.RArguments;
 import com.oracle.truffle.r.runtime.RCaller;
-import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RPromise.EagerFeedback;
 import com.oracle.truffle.r.runtime.data.RPromise.RPromiseFactory;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 import com.oracle.truffle.r.runtime.nodes.RNode;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 public abstract class OptVariablePromiseBaseNode extends PromiseNode implements EagerFeedback {
     private final BranchProfile promiseCallerProfile = BranchProfile.create();
-    private final ReadVariableNode originalRvn;
+    private final RSyntaxLookup originalRvn;
     @Child private FrameSlotNode frameSlotNode;
     @Child private RNode fallback = null;
     @Child private LocalReadVariableNode readNode;
     private final int wrapIndex;
 
-    public OptVariablePromiseBaseNode(RPromiseFactory factory, ReadVariableNode rvn, int wrapIndex) {
+    public OptVariablePromiseBaseNode(RPromiseFactory factory, RSyntaxLookup lookup, int wrapIndex) {
         super(factory);
         // Should be caught by optimization check
-        assert !rvn.isForceForTypeCheck() && rvn.getMode() == RType.Any;
-        this.originalRvn = rvn;
-        this.frameSlotNode = FrameSlotNode.create(rvn.getIdentifier(), false);
-        this.readNode = LocalReadVariableNode.create(rvn.getIdentifier(), false);
+        assert !lookup.isFunctionLookup();
+        this.originalRvn = lookup;
+        this.frameSlotNode = FrameSlotNode.create(lookup.getIdentifier(), false);
+        this.readNode = LocalReadVariableNode.create(lookup.getIdentifier(), false);
         this.wrapIndex = wrapIndex;
     }
 
     @Override
     public RSyntaxNode getPromiseExpr() {
-        return originalRvn;
+        return (RSyntaxNode) originalRvn;
     }
 
     @Override
@@ -133,6 +132,6 @@ public abstract class OptVariablePromiseBaseNode extends PromiseNode implements
 
     @Override
     public RSyntaxNode getRSyntaxNode() {
-        return originalRvn;
+        return (RSyntaxNode) originalRvn;
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java
index 3780418d1675fe83fe3101d4ad6bdc6a021b14fd..a9912feba90ea092a00e3a2f725d2b12e3ab4aaf 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java
@@ -38,7 +38,6 @@ import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxElement;
-import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 // transcribed from /src/library/methods/src/methods_list_dispatch.c (R_loadMethod function)
 abstract class LoadMethod extends RBaseNode {
@@ -119,7 +118,7 @@ abstract class LoadMethod extends RBaseNode {
             REnvironment methodsEnv = (REnvironment) methodsEnvRead.execute(frame, REnvironment.getNamespaceRegistry().getFrame(regFrameAccessProfile));
             if (loadMethodFind == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                loadMethodFind = insert(ReadVariableNode.createFunctionLookup(RSyntaxNode.INTERNAL, RRuntime.R_LOAD_METHOD_NAME));
+                loadMethodFind = insert(ReadVariableNode.createFunctionLookup(RRuntime.R_LOAD_METHOD_NAME));
                 currentFunction = (RFunction) loadMethodFind.execute(frame, methodsEnv.getFrame());
                 loadMethodFunction = currentFunction;
                 loadMethodCall = insert(CallRFunctionNode.create(loadMethodFunction.getTarget()));