diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
index f65362c9b5ed008d5b3f42e2c9326107c20d8694..1d1eab31ccaad035899ede359b5ba5529b639c69 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
@@ -76,7 +76,7 @@ public final class REngine implements RContext.Engine {
      * @param crashOnFatalErrorArg if {@code true} any unhandled exception will terminate the
      *            process.
      * @return a {@link VirtualFrame} that can be passed to
-     *         {@link #parseAndEval(String, String, VirtualFrame, REnvironment, boolean, boolean)}
+     *         {@link #parseAndEval(String, String, MaterializedFrame, REnvironment, boolean, boolean)}
      */
     public static VirtualFrame initialize(String[] commandArgs, ConsoleHandler consoleHandler, boolean crashOnFatalErrorArg, boolean headless) {
         singleton.startTime = System.nanoTime();
@@ -101,16 +101,16 @@ public final class REngine implements RContext.Engine {
         ROptions.initialize();
         RProfile.initialize();
         // eval the system profile
-        singleton.parseAndEval("<system_profile>", RProfile.systemProfile(), baseFrame, REnvironment.baseEnv(), false, false);
+        singleton.parseAndEval("<system_profile>", RProfile.systemProfile(), baseFrame.materialize(), REnvironment.baseEnv(), false, false);
         REnvironment.packagesInitialize(RPackages.initialize());
         RPackageVariables.initialize(); // TODO replace with R code
         String siteProfile = RProfile.siteProfile();
         if (siteProfile != null) {
-            singleton.parseAndEval("<site_profile>", siteProfile, baseFrame, REnvironment.baseEnv(), false, false);
+            singleton.parseAndEval("<site_profile>", siteProfile, baseFrame.materialize(), REnvironment.baseEnv(), false, false);
         }
         String userProfile = RProfile.userProfile();
         if (userProfile != null) {
-            singleton.parseAndEval("<user_profile>", userProfile, globalFrame, REnvironment.globalEnv(), false, false);
+            singleton.parseAndEval("<user_profile>", userProfile, globalFrame.materialize(), REnvironment.globalEnv(), false, false);
         }
         return globalFrame;
     }
@@ -119,7 +119,7 @@ public final class REngine implements RContext.Engine {
         return singleton;
     }
 
-    public void loadDefaultPackage(String name, VirtualFrame frame, REnvironment envForFrame) {
+    public void loadDefaultPackage(String name, MaterializedFrame frame, REnvironment envForFrame) {
         RBuiltinPackages.load(name, frame, envForFrame);
     }
 
@@ -135,14 +135,14 @@ public final class REngine implements RContext.Engine {
         return childTimes;
     }
 
-    public Object parseAndEval(String sourceDesc, String rscript, VirtualFrame frame, REnvironment envForFrame, boolean printResult, boolean allowIncompleteSource) {
+    public Object parseAndEval(String sourceDesc, String rscript, MaterializedFrame frame, REnvironment envForFrame, boolean printResult, boolean allowIncompleteSource) {
         return parseAndEvalImpl(new ANTLRStringStream(rscript), Source.asPseudoFile(rscript, sourceDesc), frame, printResult, allowIncompleteSource);
     }
 
     public Object parseAndEvalTest(String rscript, boolean printResult) {
         VirtualFrame frame = RRuntime.createNonFunctionFrame();
         REnvironment.resetForTest(frame);
-        return parseAndEvalImpl(new ANTLRStringStream(rscript), Source.asPseudoFile(rscript, "<test_input>"), frame, printResult, false);
+        return parseAndEvalImpl(new ANTLRStringStream(rscript), Source.asPseudoFile(rscript, "<test_input>"), frame.materialize(), printResult, false);
     }
 
     public class ParseException extends Exception {
@@ -188,7 +188,7 @@ public final class REngine implements RContext.Engine {
         return eval(ffunction, (RNode) expr.getRep(), envir, enclos);
     }
 
-    public Object eval(RExpression expr, VirtualFrame frame) {
+    public Object eval(RExpression expr, MaterializedFrame frame) {
         Object result = null;
         for (int i = 0; i < expr.getLength(); i++) {
             result = expr.getDataAt(i);
@@ -202,7 +202,7 @@ public final class REngine implements RContext.Engine {
 
     private static final String EVAL_FUNCTION_NAME = "<eval wrapper>";
 
-    public Object eval(RLanguage expr, VirtualFrame frame) {
+    public Object eval(RLanguage expr, MaterializedFrame frame) {
         RNode n = expr.getType() == RLanguage.Type.RNODE ? (RNode) expr.getRep() : makeCallNode(expr);
         RootCallTarget callTarget = doMakeCallTarget(n, EVAL_FUNCTION_NAME);
         return runCall(callTarget, frame, false, false);
@@ -281,12 +281,12 @@ public final class REngine implements RContext.Engine {
     private static Object eval(RFunction function, RootCallTarget callTarget, SourceSection callSrc, REnvironment envir, REnvironment enclos) throws PutException {
         MaterializedFrame envFrame = envir.getFrame();
         // Here we create fake frame that wraps the original frame's context and has an only
-        // slightly changed arguments array (functio and callSrc).
-        VirtualFrame vFrame = VirtualEvalFrame.create(envFrame, function, callSrc);
+        // slightly changed arguments array (function and callSrc).
+        MaterializedFrame vFrame = VirtualEvalFrame.create(envFrame, function, callSrc);
         return runCall(callTarget, vFrame, false, false);
     }
 
-    public Object evalPromise(RPromise promise, VirtualFrame frame) throws RError {
+    public Object evalPromise(RPromise promise, MaterializedFrame frame) throws RError {
         return runCall(promise.getClosure().getCallTarget(), frame, false, false);
     }
 
@@ -304,7 +304,7 @@ public final class REngine implements RContext.Engine {
         }
     }
 
-    private static Object parseAndEvalImpl(ANTLRStringStream stream, Source source, VirtualFrame frame, boolean printResult, boolean allowIncompleteSource) {
+    private static Object parseAndEvalImpl(ANTLRStringStream stream, Source source, MaterializedFrame frame, boolean printResult, boolean allowIncompleteSource) {
         try {
             RootCallTarget callTarget = doMakeCallTarget(parseToRNode(stream, source), "<repl wrapper>");
             Object result = runCall(callTarget, frame, printResult, true);
@@ -393,12 +393,12 @@ public final class REngine implements RContext.Engine {
      * {@code frame} will be accessible via {@code newFrame.getArguments()[0]}, and the execution
      * will continue using {@code frame}.
      */
-    private static Object runCall(RootCallTarget callTarget, VirtualFrame frame, boolean printResult, boolean topLevel) {
+    private static Object runCall(RootCallTarget callTarget, MaterializedFrame frame, boolean printResult, boolean topLevel) {
         Object result = null;
         try {
             try {
                 // FIXME: callTargets should only be called via Direct/IndirectCallNode
-                result = callTarget.call(frame.materialize());
+                result = callTarget.call(frame);
             } catch (ControlFlowException cfe) {
                 throw RError.error(RError.Message.NO_LOOP_FOR_BREAK_NEXT);
             }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackage.java
index bf5a5edc9eb0b96da3e592cfd45a4e5ef149cb9b..fcae1da1dd65e5a620ac08624aa57b1b77c4b553 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackage.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackage.java
@@ -128,7 +128,7 @@ public abstract class RBuiltinPackage {
     /**
      * Runtime component of the package initialization process.
      */
-    public void loadSources(VirtualFrame frame, REnvironment envForFrame) {
+    public void loadSources(MaterializedFrame frame, REnvironment envForFrame) {
         this.env = envForFrame;
         for (RBuiltinFactory factory : builtins.values()) {
             if (factory.getPackage() == this) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java
index b44c78ab5ae8697b6aeb445ee56cbb696609266e..fee2b189759d8b3fdda6d13a4fcab366d6246889 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java
@@ -67,7 +67,7 @@ public final class RBuiltinPackages implements RBuiltinLookup {
         return packages;
     }
 
-    public static void load(String name, VirtualFrame frame, REnvironment envForFrame) {
+    public static void load(String name, MaterializedFrame frame, REnvironment envForFrame) {
         RBuiltinPackage pkg = packages.get(name);
         if (pkg == null) {
             Utils.fail("unknown default package: " + name);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BrowserFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BrowserFunctions.java
index 22203436681c78187f1050d0a52386f5650b8044..c944e1ba0bf7e538663b4ab1a3284115ccb7b5e6 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BrowserFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BrowserFunctions.java
@@ -116,7 +116,7 @@ public class BrowserFunctions {
                         }
 
                         default:
-                            RContext.getEngine().parseAndEval("<browser_input>", input, frame, callerEnv, true, false);
+                            RContext.getEngine().parseAndEval("<browser_input>", input, frame.materialize(), callerEnv, true, false);
                             break;
                     }
                 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java
index 161b1a6d802a37076b0f89db3a3fe38ef770990f..60c52224695001b2fcfa626763825d68cb2f62ba 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java
@@ -109,9 +109,9 @@ public class EvalFunctions {
             Object expr = checkConvertSymbol(exprArg);
 
             if (expr instanceof RExpression) {
-                return RContext.getEngine().eval((RExpression) exprArg, frame);
+                return RContext.getEngine().eval((RExpression) exprArg, frame.materialize());
             } else if (expr instanceof RLanguage) {
-                return RContext.getEngine().eval((RLanguage) exprArg, frame);
+                return RContext.getEngine().eval((RLanguage) exprArg, frame.materialize());
             } else {
                 // just return value
                 return expr;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java
index 11ae34c61c7d1e1b56019b1b1b4420f6117c6578..46d851c7e3bbceb2b53c4de85b35251ca315f8a9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java
@@ -52,7 +52,7 @@ public abstract class Order extends RBuiltinNode {
     @Child private BooleanOperation ge = BinaryCompare.GREATER_EQUAL.create();
     @Child private BooleanOperation gt = BinaryCompare.GREATER_THAN.create();
 
-    // specialisations for one parameter
+    // specializations for one parameter
 
     @SuppressWarnings("unused")
     @Specialization(guards = "empty")
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/expressions/ExpressionExecutorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/expressions/ExpressionExecutorNode.java
index 13c41236c6f577815d57dec55f3fb5d4f45ee39b..5d263f6566b458ee4b88de7ea4b6662bd61ad3da 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/expressions/ExpressionExecutorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/expressions/ExpressionExecutorNode.java
@@ -35,7 +35,7 @@ import com.oracle.truffle.r.runtime.data.*;
  * {@link RNode}. This in essence bridges the gap between code as runtime data and executed code. To
  * make this as efficient as possible, it creates a PIC (polymorphic inline cache) for a certain
  * number of known expressions before delegating to a generic version which uses the
- * {@link Engine#eval(RLanguage, VirtualFrame)} functionality.
+ * {@link Engine#eval(RLanguage, MaterializedFrame)} functionality.
  */
 public abstract class ExpressionExecutorNode extends Node {
 
@@ -58,7 +58,7 @@ public abstract class ExpressionExecutorNode extends Node {
             // Specialize below
             ExpressionExecutorNode replacement;
             if (picDepth < INLINE_CACHE_SIZE) {
-                this.incPicDepth();
+                incPicDepth();
                 replacement = new DirectExpressionExecutorNode(node, this);
             } else {
                 replacement = new GenericExpressionExecutorNode();
@@ -96,7 +96,7 @@ public abstract class ExpressionExecutorNode extends Node {
     private static final class GenericExpressionExecutorNode extends ExpressionExecutorNode {
         @Override
         public Object execute(VirtualFrame frame, RNode node) {
-            return RContext.getEngine().eval(new RLanguage(node), frame);
+            return RContext.getEngine().eval(new RLanguage(node), frame.materialize());
         }
     }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java
index cca44faf66dcb7184931c45ad535138f624b0959..886b1681d864939d95d162906331073b651490c6 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java
@@ -152,7 +152,7 @@ public final class RContext extends ExecutionContext {
          * @param frame for evaluating any associated R code
          * @param envForFrame the namespace environment associated with the package.
          */
-        void loadDefaultPackage(String name, VirtualFrame frame, REnvironment envForFrame);
+        void loadDefaultPackage(String name, MaterializedFrame frame, REnvironment envForFrame);
 
         /**
          * Return the {@link RFunction} for the builtin {@code name}.
@@ -173,7 +173,7 @@ public final class RContext extends ExecutionContext {
          * @param envForFrame the environment that {@code frame} is bound to.
          * @return the object returned by the evaluation or {@code null} if an error occurred.
          */
-        Object parseAndEval(String sourceDesc, String rscript, VirtualFrame frame, REnvironment envForFrame, boolean printResult, boolean allowIncompleteSource);
+        Object parseAndEval(String sourceDesc, String rscript, MaterializedFrame frame, REnvironment envForFrame, boolean printResult, boolean allowIncompleteSource);
 
         static final Object INCOMPLETE_SOURCE = new Object();
 
@@ -219,18 +219,18 @@ public final class RContext extends ExecutionContext {
         /**
          * Evaluate {@code expr} in {@code frame}.
          */
-        Object eval(RExpression expr, VirtualFrame frame);
+        Object eval(RExpression expr, MaterializedFrame frame);
 
         /**
-         * Variant of {@link #eval(RExpression, VirtualFrame)} for a single language element.
+         * Variant of {@link #eval(RExpression, MaterializedFrame)} for a single language element.
          */
-        Object eval(RLanguage expr, VirtualFrame frame);
+        Object eval(RLanguage expr, MaterializedFrame frame);
 
         /**
-         * Evaluate a promise in the given frame, where we can use the {@link VirtualFrame}) of the
-         * caller directly). This should <b>only</b> be called by the {@link RPromise} class.
+         * Evaluate a promise in the given frame, where we can use the {@link MaterializedFrame}) of
+         * the caller directly). This should <b>only</b> be called by the {@link RPromise} class.
          */
-        Object evalPromise(RPromise expr, VirtualFrame frame) throws RError;
+        Object evalPromise(RPromise expr, MaterializedFrame frame) throws RError;
 
         /**
          * Evaluate a promise in the {@link MaterializedFrame} stored with the promise. This should
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
index 72bea8eaefdfec9f11be4ab1b25d640e6d69fc64..e73169627cbd7b2ac88eb3e878301cb38555f037 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
@@ -141,9 +141,9 @@ public final class RError extends RuntimeException {
             if (errorExpr instanceof RLanguage || errorExpr instanceof RExpression) {
                 VirtualFrame frame = Utils.getActualCurrentFrame();
                 if (errorExpr instanceof RLanguage) {
-                    RContext.getEngine().eval((RLanguage) errorExpr, frame);
+                    RContext.getEngine().eval((RLanguage) errorExpr, frame.materialize());
                 } else if (errorExpr instanceof RExpression) {
-                    RContext.getEngine().eval((RExpression) errorExpr, frame);
+                    RContext.getEngine().eval((RExpression) errorExpr, frame.materialize());
                 }
             } else {
                 // GnuR checks this earlier when the option is set
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java
index 32afc25f79d16e2c74f68c282a21992fd3f110b1..f3228cb2f304f4bc5589f3300a8014558de477ff 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java
@@ -220,7 +220,7 @@ public final class RPromise extends RLanguageRep {
                 newValue = doEvalArgument(callSrc);
             } else {
                 assert isInOriginFrame(frame, profile);
-                newValue = doEvalArgument(frame);
+                newValue = doEvalArgument(frame.materialize());
             }
 
             setValue(newValue);
@@ -255,7 +255,7 @@ public final class RPromise extends RLanguageRep {
         return result;
     }
 
-    protected Object doEvalArgument(VirtualFrame frame) {
+    protected Object doEvalArgument(MaterializedFrame frame) {
         Object result = null;
         try {
             result = RContext.getEngine().evalPromise(this, frame);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java
index 0f5bac28793418a2356c9c9f6271988679f7a8a3..110dd38fe1e1b97e820f8d4b902930c3cfce2d3a 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java
@@ -231,7 +231,7 @@ public abstract class REnvironment implements RAttributable {
         initSearchList();
 
         // load base package first
-        RContext.getEngine().loadDefaultPackage("base", baseFrame, baseEnv);
+        RContext.getEngine().loadDefaultPackage("base", baseFrame.materialize(), baseEnv);
     }
 
     public static void packagesInitialize(ArrayList<RPackage> rPackages) {
@@ -240,7 +240,7 @@ public abstract class REnvironment implements RAttributable {
         for (RPackage rPackage : rPackages) {
             VirtualFrame pkgFrame = RRuntime.createNonFunctionFrame();
             Package pkgEnv = new Package(pkgParent, rPackage.name, pkgFrame, rPackage.path);
-            RContext.getEngine().loadDefaultPackage(rPackage.name, pkgFrame, pkgEnv);
+            RContext.getEngine().loadDefaultPackage(rPackage.name, pkgFrame.materialize(), pkgEnv);
             attach(2, pkgEnv);
             pkgParent = pkgEnv;
         }
diff --git a/com.oracle.truffle.r.shell/src/com/oracle/truffle/r/shell/RCommand.java b/com.oracle.truffle.r.shell/src/com/oracle/truffle/r/shell/RCommand.java
index d728bebcfb48db833d5bef93a008e33c8c9d4b46..bcf15f2f0b37158033138982ca25344d20fd3029 100644
--- a/com.oracle.truffle.r.shell/src/com/oracle/truffle/r/shell/RCommand.java
+++ b/com.oracle.truffle.r.shell/src/com/oracle/truffle/r/shell/RCommand.java
@@ -155,7 +155,7 @@ public class RCommand {
             String content = new String(bytes);
             JLineConsoleHandler consoleHandler = new JLineConsoleHandler(false, new ConsoleReader(null, System.out));
             VirtualFrame frame = REngine.initialize(commandArgs, consoleHandler, true, true);
-            REngine.getInstance().parseAndEval(filePath, content, frame, REnvironment.globalEnv(), false, false);
+            REngine.getInstance().parseAndEval(filePath, content, frame.materialize(), REnvironment.globalEnv(), false, false);
         } catch (IOException ex) {
             Utils.fail("unexpected error reading file input");
         }
@@ -180,7 +180,7 @@ public class RCommand {
                     continue;
                 }
 
-                while (REngine.getInstance().parseAndEval("<shell_input>", input, globalFrame, REnvironment.globalEnv(), true, true) == Engine.INCOMPLETE_SOURCE) {
+                while (REngine.getInstance().parseAndEval("<shell_input>", input, globalFrame.materialize(), REnvironment.globalEnv(), true, true) == Engine.INCOMPLETE_SOURCE) {
                     console.setPrompt(SLAVE.getValue() ? "" : "+ ");
                     String additionalInput = console.readLine();
                     if (additionalInput == null) {