diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java
index 3cf0a1367f513789ec5e782884f4b1f8f3cc4cf6..34579323fc4d1d20b95763cad9fbec96407904ac 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java
@@ -40,8 +40,8 @@ public abstract class Attributes extends RBuiltinNode {
 
     private final BranchProfile rownamesBranch = BranchProfile.create();
 
-    @Specialization(guards = "!hasAttributes(vector)")
-    protected RNull attributesNull(@SuppressWarnings("unused") RAbstractVector vector) {
+    @Specialization(guards = "!hasAttributes(container)")
+    protected Object attributesNull(@SuppressWarnings("unused") RAbstractContainer container) {
         controlVisibility();
         return RNull.instance;
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Body.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Body.java
index d3fd82b55e4ef5bc5be9383fd5b0337c1fa021a0..cb0c233e0838e6adf604eabac4221971d471bd22 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Body.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Body.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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
@@ -22,29 +22,25 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import com.oracle.truffle.api.dsl.Fallback;
-import com.oracle.truffle.api.dsl.Specialization;
-import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode;
-import com.oracle.truffle.r.runtime.RBuiltin;
+import static com.oracle.truffle.r.runtime.RBuiltinKind.*;
 
-import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL;
-
-import com.oracle.truffle.r.runtime.data.RDataFactory;
-import com.oracle.truffle.r.runtime.data.RFunction;
-import com.oracle.truffle.r.runtime.data.RLanguage;
-import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.r.nodes.builtin.*;
+import com.oracle.truffle.r.nodes.function.*;
+import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.data.*;
 
 @RBuiltin(name = "body", kind = INTERNAL, parameterNames = {"fun"})
 public abstract class Body extends RBuiltinNode {
+
     @Specialization
     public RLanguage doBody(RFunction fun) {
         FunctionDefinitionNode fdn = (FunctionDefinitionNode) fun.getRootNode();
         return RDataFactory.createLanguage(fdn.getUninitializedBody());
     }
 
-    @Fallback
-    public RNull doBody(@SuppressWarnings("unused") Object fun) {
+    @Specialization(guards = "!isRFunction(fun)")
+    public RNull doBodyNull(@SuppressWarnings("unused") Object fun) {
         return RNull.instance;
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
index f43c98fcda9923925e8f9d9b404b73ece452a4c8..9cbcdc841a3da66282767d231b440bed507d9e63 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
@@ -187,12 +187,11 @@ public class EnvFunctions {
     @RBuiltin(name = "environment", kind = INTERNAL, parameterNames = {"fun"})
     public abstract static class Environment extends RBuiltinNode {
 
-        private final ConditionProfile isFunctionProfile = ConditionProfile.createBinaryProfile();
         private final ConditionProfile createEnvironmentProfile = ConditionProfile.createBinaryProfile();
         private final PromiseDeoptimizeFrameNode deoptFrameNode = new PromiseDeoptimizeFrameNode();
 
         @Specialization
-        protected Object environment(VirtualFrame frame, @SuppressWarnings("unused") RNull x) {
+        protected Object environment(VirtualFrame frame, @SuppressWarnings("unused") RNull fun) {
             controlVisibility();
             Frame callerFrame = Utils.getCallerFrame(frame, FrameAccess.MATERIALIZE);
             MaterializedFrame matFrame = callerFrame.materialize();
@@ -205,24 +204,24 @@ public class EnvFunctions {
          * cannot both have a specialization for {@link RFunction} and one for {@link Object}, but
          * an object that is not an {@link RFunction} is legal and must return {@code NULL}.
          */
-        @Fallback
-        protected Object environment(Object funcArg) {
+        @Specialization
+        protected Object environment(RFunction fun) {
             controlVisibility();
-            if (isFunctionProfile.profile(funcArg instanceof RFunction)) {
-                RFunction func = (RFunction) funcArg;
-                Frame enclosing = func.getEnclosingFrame();
-                REnvironment env = RArguments.getEnvironment(enclosing);
-                if (createEnvironmentProfile.profile(env == null)) {
-                    return REnvironment.createEnclosingEnvironments(enclosing.materialize());
-                } else {
-                    return env;
-                }
+            Frame enclosing = fun.getEnclosingFrame();
+            REnvironment env = RArguments.getEnvironment(enclosing);
+            if (createEnvironmentProfile.profile(env == null)) {
+                return REnvironment.createEnclosingEnvironments(enclosing.materialize());
             } else {
-                // Not an error according to GnuR
-                return RNull.instance;
+                return env;
             }
         }
 
+        @Specialization(guards = {"!isRNull(fun)", "!isRFunction(fun)"})
+        protected Object environment(@SuppressWarnings("unused") Object fun) {
+            // Not an error according to GnuR
+            controlVisibility();
+            return RNull.instance;
+        }
     }
 
     @RBuiltin(name = "environmentName", kind = INTERNAL, parameterNames = {"fun"})
@@ -234,7 +233,7 @@ public class EnvFunctions {
             return env.getName();
         }
 
-        @Fallback
+        @Specialization(guards = "!isREnvironment(env)")
         protected String environmentName(@SuppressWarnings("unused") Object env) {
             controlVisibility();
             // Not an error according to GnuR
@@ -282,19 +281,17 @@ public class EnvFunctions {
 
     }
 
-    private interface BindingErrorMixin {
-        default void check(SourceSection source, Object sym, Object env) throws RError {
-            if (!(sym instanceof RSymbol)) {
-                throw RError.error(source, RError.Message.NOT_A_SYMBOL);
-            }
-            if (!(env instanceof REnvironment)) {
-                throw RError.error(source, RError.Message.NOT_AN_ENVIRONMENT);
-            }
+    private static RuntimeException typeError(SourceSection source, Object sym, Object env) {
+        if (!(sym instanceof RSymbol)) {
+            throw RError.error(source, RError.Message.NOT_A_SYMBOL);
+        } else {
+            assert !(env instanceof REnvironment);
+            throw RError.error(source, RError.Message.NOT_AN_ENVIRONMENT);
         }
     }
 
     @RBuiltin(name = "lockBinding", kind = INTERNAL, parameterNames = {"sym", "env"})
-    public abstract static class LockBinding extends RInvisibleBuiltinNode implements BindingErrorMixin {
+    public abstract static class LockBinding extends RInvisibleBuiltinNode {
         @Specialization
         protected Object lockBinding(RSymbol sym, REnvironment env) {
             controlVisibility();
@@ -302,61 +299,38 @@ public class EnvFunctions {
             return RNull.instance;
         }
 
-        @Specialization
-        protected Object lockBinding(RAbstractStringVector name, REnvironment env) {
-            controlVisibility();
-            env.lockBinding(name.getDataAt(0));
-            return RNull.instance;
-        }
-
         @Fallback
         protected Object lockBinding(Object sym, Object env) {
-            check(getEncapsulatingSourceSection(), sym, env);
-            return RNull.instance;
+            throw typeError(getEncapsulatingSourceSection(), sym, env);
         }
     }
 
     @RBuiltin(name = "unlockBinding", kind = INTERNAL, parameterNames = {"sym", "env"})
-    public abstract static class UnlockBinding extends RInvisibleBuiltinNode implements BindingErrorMixin {
+    public abstract static class UnlockBinding extends RInvisibleBuiltinNode {
         @Specialization
-        protected Object unlockBinding(RSymbol sym, REnvironment env) {
+        protected RNull unlockBinding(RSymbol sym, REnvironment env) {
             controlVisibility();
             env.unlockBinding(sym.getName());
             return RNull.instance;
         }
 
-        @Specialization
-        protected Object unlockBinding(RAbstractStringVector name, REnvironment env) {
-            controlVisibility();
-            env.unlockBinding(name.getDataAt(0));
-            return RNull.instance;
-        }
-
         @Fallback
-        protected Object unlockBinding(Object sym, Object env) {
-            check(getEncapsulatingSourceSection(), sym, env);
-            return RNull.instance;
+        protected Object unlockBindings(Object sym, Object env) {
+            throw typeError(getEncapsulatingSourceSection(), sym, env);
         }
     }
 
     @RBuiltin(name = "bindingIsLocked", kind = INTERNAL, parameterNames = {"sym", "env"})
-    public abstract static class BindingIsLocked extends RBuiltinNode implements BindingErrorMixin {
+    public abstract static class BindingIsLocked extends RBuiltinNode {
         @Specialization
         protected Object bindingIsLocked(RSymbol sym, REnvironment env) {
             controlVisibility();
             return RDataFactory.createLogicalVectorFromScalar(env.bindingIsLocked(sym.getName()));
         }
 
-        @Specialization
-        protected Object bindingIsLocked(RAbstractStringVector name, REnvironment env) {
-            controlVisibility();
-            return RDataFactory.createLogicalVectorFromScalar(env.bindingIsLocked(name.getDataAt(0)));
-        }
-
         @Fallback
         protected Object bindingIsLocked(Object sym, Object env) {
-            check(getEncapsulatingSourceSection(), sym, env);
-            return RNull.instance;
+            throw typeError(getEncapsulatingSourceSection(), sym, env);
         }
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java
index 750222e29f00a1ec1ae9cfcb51c4128e900f6f40..97b3b9168c466fff75bafc40b2e6f1d5a967c28b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java
@@ -119,7 +119,7 @@ public class InfixEmulationFunctions {
 
         protected abstract Object execute(VirtualFrame frame, Object op);
 
-        @Child private PromiseHelperNode promiseHelper = new PromiseHelperNode();
+        @Child private PromiseHelperNode promiseHelper;
         @Child private PromiseEvaluator evalRecursive;
 
         protected Object evalRecursive(VirtualFrame frame, Object op) {
@@ -130,14 +130,18 @@ public class InfixEmulationFunctions {
             return evalRecursive.execute(frame, op);
         }
 
-        @Specialization
-        protected Object eval(VirtualFrame frame, RPromise p) {
-            return promiseHelper.evaluate(frame, p);
+        @Specialization(guards = {"!isRPromise(op)", "!isRArgsValuesAndNames(op)"})
+        protected Object eval(Object op) {
+            return op;
         }
 
         @Specialization
-        protected RAbstractVector eval(RAbstractVector op) {
-            return op;
+        protected Object eval(VirtualFrame frame, RPromise p) {
+            if (promiseHelper == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                promiseHelper = insert(new PromiseHelperNode());
+            }
+            return promiseHelper.evaluate(frame, p);
         }
 
         @Specialization(guards = "!argsEmpty(args)")
@@ -154,15 +158,9 @@ public class InfixEmulationFunctions {
             return args;
         }
 
-        @Fallback
-        protected Object eval(Object op) {
-            return op;
-        }
-
         protected boolean argsEmpty(RArgsValuesAndNames args) {
             return args.length() == 0;
         }
-
     }
 
     public abstract static class AccessArrayBuiltin extends RBuiltinNode {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RNode.java
index 2370cc3ba659b2e8c9940464cd934cebad2eb66c..40943001e18bf5d808a42a2e18a76d63fa1e20a4 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RNode.java
@@ -241,4 +241,92 @@ public abstract class RNode extends Node implements RSyntaxNode, RInstrumentable
             }
         }
     }
+
+    protected boolean isRAbstractContainer(Object value) {
+        return value instanceof RAbstractContainer;
+    }
+
+    protected boolean isRAbstractVector(Object value) {
+        return value instanceof RAbstractVector;
+    }
+
+    protected boolean isRAbstractIntVector(Object value) {
+        return value instanceof RAbstractIntVector;
+    }
+
+    protected boolean isRAbstractDoubleVector(Object value) {
+        return value instanceof RAbstractDoubleVector;
+    }
+
+    protected boolean isRAbstractComplexVector(Object value) {
+        return value instanceof RAbstractComplexVector;
+    }
+
+    protected boolean isRAbstractRawVector(Object value) {
+        return value instanceof RAbstractRawVector;
+    }
+
+    protected boolean isRAbstractStringVector(Object value) {
+        return value instanceof RAbstractStringVector;
+    }
+
+    protected boolean isRAbstractLogicalVector(Object value) {
+        return value instanceof RAbstractLogicalVector;
+    }
+
+    protected boolean isRList(Object value) {
+        return value instanceof RList;
+    }
+
+    protected boolean isRDataFrame(Object value) {
+        return value instanceof RDataFrame;
+    }
+
+    protected boolean isRFactor(Object value) {
+        return value instanceof RFactor;
+    }
+
+    protected boolean isRPromise(Object value) {
+        return value instanceof RPromise;
+    }
+
+    protected boolean isRLanguage(Object value) {
+        return value instanceof RLanguage;
+    }
+
+    protected boolean isRExpression(Object value) {
+        return value instanceof RExpression;
+    }
+
+    protected boolean isRFunction(Object value) {
+        return value instanceof RFunction;
+    }
+
+    protected boolean isREnvironment(Object value) {
+        return value instanceof REnvironment;
+    }
+
+    protected boolean isRConnection(Object value) {
+        return value instanceof RConnection;
+    }
+
+    protected boolean isRPairList(Object value) {
+        return value instanceof RPairList;
+    }
+
+    protected boolean isRSymbol(Object value) {
+        return value instanceof RSymbol;
+    }
+
+    protected boolean isRArgsValuesAndNames(Object value) {
+        return value instanceof RArgsValuesAndNames;
+    }
+
+    protected boolean isRMissing(Object value) {
+        return value == RMissing.instance;
+    }
+
+    protected boolean isRNull(Object value) {
+        return value == RNull.instance;
+    }
 }