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 0bcfa1aecf9fe8daeef62d023fb2e398b08ebd4b..cf78e10d6a1483ac8f996b28d2314c7eed12a42a 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
@@ -12,7 +12,12 @@
 package com.oracle.truffle.r.library.methods;
 
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lengthGt;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.singleElement;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
+
+import java.util.function.Function;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
@@ -50,9 +55,9 @@ import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RS4Object;
+import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.ffi.DLL;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
@@ -285,39 +290,56 @@ public class MethodsListDispatch {
         }
     }
 
-    private static String checkSingleString(Object o, boolean nonEmpty, String what, RBaseNode node, ClassHierarchyScalarNode classHierarchyNode) {
-        if (o instanceof RAbstractStringVector) {
-            RAbstractStringVector vec = (RAbstractStringVector) o;
-            if (vec.getLength() != 1) {
-                throw RError.error(node, RError.Message.SINGLE_STRING_TOO_LONG, what, vec.getLength());
-            }
-            String s = vec.getDataAt(0);
-            if (nonEmpty && s.length() == 0) {
-                throw RError.error(node, RError.Message.NON_EMPTY_STRING, what);
-            }
-            return s;
-        } else {
-            throw RError.error(node, RError.Message.SINGLE_STRING_WRONG_TYPE, what, classHierarchyNode.executeString(o));
-        }
-    }
-
     public abstract static class R_getGeneric extends RExternalBuiltinNode.Arg4 {
 
-        @Child private ClassHierarchyScalarNode classHierarchyNode = ClassHierarchyScalarNodeGen.create();
         @Child private GetGenericInternal getGenericInternal = GetGenericInternalNodeGen.create();
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            Function<Object, String> clsHierFn = ClassHierarchyScalarNode::get;
+
+            //@formatter:off
+            Function<Object, Integer> vecLenFn = arg -> ((RAbstractStringVector) arg).getLength();
+
+            String msg0 = "The argument \"f\" to getGeneric";
+            casts.arg(0, "f").
+                defaultError(RError.NO_CALLER, RError.Message.SINGLE_STRING_WRONG_TYPE, msg0, clsHierFn).
+                mustNotBeNull().
+                mustBe(stringValue()).
+                asStringVector().
+                mustBe(singleElement(), RError.NO_CALLER, RError.Message.SINGLE_STRING_TOO_LONG, msg0, vecLenFn).
+                findFirst().
+                mustBe(lengthGt(0), RError.NO_CALLER, RError.Message.NON_EMPTY_STRING, msg0);
+
+            casts.arg(1, "mustFind").
+                asLogicalVector().
+                findFirst(RRuntime.LOGICAL_NA).
+                map(toBoolean());
+
+            casts.arg(2, "env").
+                mustNotBeNull().
+                mustBe(instanceOf(REnvironment.class));
+
+            String msg1 = "The argument \"package\" to getGeneric";
+            casts.arg(3, "package").
+                defaultError(RError.NO_CALLER, RError.Message.SINGLE_STRING_WRONG_TYPE, msg1, clsHierFn).
+                mustNotBeNull().
+                mustBe(stringValue()).
+                asStringVector().
+                mustBe(singleElement(), RError.NO_CALLER, RError.Message.SINGLE_STRING_TOO_LONG, msg1, vecLenFn).
+                findFirst();
+            //@formatter:on
+        }
+
         @Specialization
-        protected Object getGeneric(RAbstractVector nameVec, RAbstractVector mustFindVec, REnvironment env, RAbstractVector packageVec) {
-            String name = checkSingleString(nameVec, true, "The argument \"f\" to getGeneric", this, classHierarchyNode);
-            byte mustFind = castLogical(mustFindVec);
-            String pckg = checkSingleString(packageVec, false, "The argument \"package\" to getGeneric", this, classHierarchyNode);
+        protected Object getGeneric(String name, boolean mustFind, REnvironment env, String pckg) {
             Object value = getGenericInternal.executeObject(name, env, pckg);
             if (value == RNull.instance) {
-                if (mustFind == RRuntime.LOGICAL_TRUE) {
+                if (mustFind) {
                     if (env == RContext.getInstance().stateREnvironment.getGlobalEnv()) {
-                        throw RError.error(this, RError.Message.NO_GENERIC_FUN, name);
+                        throw RError.error(RError.NO_CALLER, RError.Message.NO_GENERIC_FUN, name);
                     } else {
-                        throw RError.error(this, RError.Message.NO_GENERIC_FUN_IN_ENV, name);
+                        throw RError.error(RError.NO_CALLER, RError.Message.NO_GENERIC_FUN_IN_ENV, name);
                     }
                 }
             }
@@ -375,6 +397,22 @@ public class MethodsListDispatch {
             return generic == null ? RNull.instance : generic;
         }
 
+        private static String checkSingleString(Object o, boolean nonEmpty, String what, RBaseNode node, ClassHierarchyScalarNode classHierarchyNode) {
+            if (o instanceof RAbstractStringVector) {
+                RAbstractStringVector vec = (RAbstractStringVector) o;
+                if (vec.getLength() != 1) {
+                    throw RError.error(node, RError.Message.SINGLE_STRING_TOO_LONG, what, vec.getLength());
+                }
+                String s = vec.getDataAt(0);
+                if (nonEmpty && s.length() == 0) {
+                    throw RError.error(node, RError.Message.NON_EMPTY_STRING, what);
+                }
+                return s;
+            } else {
+                throw RError.error(node, RError.Message.SINGLE_STRING_WRONG_TYPE, what, classHierarchyNode.executeString(o));
+            }
+        }
+
         @TruffleBoundary
         private static Object slotRead(MaterializedFrame currentFrame, FrameDescriptor desc, String name) {
             FrameSlot slot = desc.findFrameSlot(name);
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java
index d852a9982c7d0af34acb3e6ab11b8b7b678b276b..784bd50cfe616d4cbaba957fa1bd9c1f2908fa67 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java
@@ -40,6 +40,7 @@ import com.oracle.truffle.api.instrumentation.SourceSectionFilter;
 import com.oracle.truffle.api.instrumentation.StandardTags;
 import com.oracle.truffle.api.nodes.RootNode;
 import com.oracle.truffle.api.source.Source;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
 import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode;
 import com.oracle.truffle.r.nodes.instrumentation.RInstrumentation;
@@ -61,6 +62,8 @@ import com.oracle.truffle.r.runtime.instrument.InstrumentationState;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxElement;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
+
 /**
  * Implements the {@code Rprof} external.
  *
@@ -79,13 +82,24 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
  */
 public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements RDataFactory.Listener, MemoryCopyTracer.Listener {
 
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg(0, "filename").mustBe(stringValue()).asStringVector().mustBe(singleElement()).findFirst();
+        casts.arg(1, "append_mode").asLogicalVector().findFirst(RRuntime.LOGICAL_NA).map(toBoolean());
+        casts.arg(2, "dinterval").asDoubleVector().findFirst(RRuntime.DOUBLE_NA);
+        casts.arg(3, "mem_profiling").asLogicalVector().findFirst(RRuntime.LOGICAL_NA).map(toBoolean());
+        casts.arg(4, "gc_profiling").asLogicalVector().findFirst(RRuntime.LOGICAL_NA).map(toBoolean());
+        casts.arg(5, "line_profiling").asLogicalVector().findFirst(RRuntime.LOGICAL_NA).map(toBoolean());
+        casts.arg(6, "numfiles").asIntegerVector().findFirst().mustBe(gte(0));
+        casts.arg(7, "bufsize").asIntegerVector().findFirst().mustBe(gte(0));
+    }
+
     @SuppressWarnings("unused")
     @Specialization
     @TruffleBoundary
-    public Object doRprof(RAbstractStringVector filenameVec, byte appendL, double intervalD, byte memProfilingL,
-                    byte gcProfilingL, byte lineProfilingL, int numFiles, int bufSize) {
+    public Object doRprof(String filename, boolean append, double intervalD, boolean memProfiling,
+                    boolean gcProfiling, boolean lineProfiling, int numFiles, int bufSize) {
         RprofState profState = RprofState.get();
-        String filename = filenameVec.getDataAt(0);
         if (filename.length() == 0) {
             // disable
             endProfiling();
@@ -94,9 +108,6 @@ public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements RDataFa
             if (profState != null && profState.out() != null) {
                 endProfiling();
             }
-            boolean append = RRuntime.fromLogical(appendL);
-            boolean memProfiling = RRuntime.fromLogical(memProfilingL);
-            boolean gcProfiling = RRuntime.fromLogical(gcProfilingL);
             try {
                 PrintStream out = new PrintStream(new FileOutputStream(filename, append));
                 if (gcProfiling) {
@@ -113,7 +124,7 @@ public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements RDataFa
                 StatementListener statementListener = new StatementListener();
                 ProfileThread profileThread = new ProfileThread(intervalInMillis, statementListener);
                 profileThread.setDaemon(true);
-                profState.initialize(out, profileThread, statementListener, intervalInMillis, RRuntime.fromLogical(lineProfilingL), memProfiling);
+                profState.initialize(out, profileThread, statementListener, intervalInMillis, lineProfiling, memProfiling);
                 profileThread.start();
             } catch (IOException ex) {
                 throw RError.error(this, RError.Message.GENERIC, String.format("Rprof: cannot open profile file '%s'", filename));
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java
index fe31a7244f53d9a75ca0c110079125ba326e33e9..b8cf2bdb964b9148910210cbebf9a314c7be6118 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java
@@ -23,6 +23,7 @@
 package com.oracle.truffle.r.nodes.builtin.base;
 
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.complexValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
 import static com.oracle.truffle.r.runtime.RDispatch.MATH_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -43,12 +44,19 @@ public abstract class Ceiling extends UnaryArithmeticBuiltinNode {
     public static final UnaryArithmeticFactory CEILING = FloorNodeGen.create();
 
     public Ceiling() {
-        super(RType.Double, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, null);
+        super(RType.Double, RError.Message.NON_NUMERIC_MATH, null);
     }
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.arg("x").mustNotBeNull(this, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION).mustBe(complexValue().not(), RError.Message.UNIMPLEMENTED_COMPLEX_FUN).asDoubleVector();
+        //@formatter:off
+        casts.arg("x").
+            defaultError(this, RError.Message.NON_NUMERIC_MATH).
+            mustNotBeNull().
+            mustBe(complexValue().not(), RError.Message.UNIMPLEMENTED_COMPLEX_FUN).
+            mustBe(numericValue()).
+            asDoubleVector(true, true, true);
+        //@formatter:on
     }
 
     @Override
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java
index ad9d29a490270da298dbea69223320e3d80f820c..39e733fef1823dde286cd2a08816303df636c05e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java
@@ -23,6 +23,7 @@
 package com.oracle.truffle.r.nodes.builtin.base;
 
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.complexValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
 import static com.oracle.truffle.r.runtime.RDispatch.MATH_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -43,12 +44,19 @@ public abstract class Floor extends UnaryArithmeticBuiltinNode {
     public static final UnaryArithmeticFactory FLOOR = FloorNodeGen.create();
 
     public Floor() {
-        super(RType.Double, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, null);
+        super(RType.Double, RError.Message.NON_NUMERIC_MATH, null);
     }
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.arg("x").mustNotBeNull(this, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION).mustBe(complexValue().not(), RError.Message.UNIMPLEMENTED_COMPLEX_FUN).asDoubleVector();
+        //@formatter:off
+        casts.arg("x").
+            defaultError(this, RError.Message.NON_NUMERIC_MATH).
+            mustNotBeNull().
+            mustBe(complexValue().not(), RError.Message.UNIMPLEMENTED_COMPLEX_FUN).
+            mustBe(numericValue()).
+            asDoubleVector(true, true, true);
+        //@formatter:on
     }
 
     @Override
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java
index 8a5488c18d78944eeb4a906301b760a75846ef0b..9c23cbd7326bf0ac9ef7347641b3dee044c30def 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,8 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.complexValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
 import static com.oracle.truffle.r.runtime.RDispatch.MATH_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -30,6 +32,7 @@ import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RComplex;
@@ -62,9 +65,22 @@ public abstract class Round extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
+        //@formatter:off
+        casts.arg("x").
+            defaultError(this, RError.Message.NON_NUMERIC_MATH).
+            mustNotBeNull().
+            mustBe(numericValue().or(complexValue()));
+
         // TODO: this should also accept vectors
         // TODO: digits argument is rounded, not simply stripped off the decimal part
-        casts.arg("digits").asIntegerVector().findFirst();
+        casts.arg("digits").
+            defaultError(this, RError.Message.NON_NUMERIC_MATH).
+            mustNotBeNull().
+            mustBe(numericValue().or(complexValue())).
+            asIntegerVector().
+            findFirst();
+
+        //@formatter:on
     }
 
     @Specialization
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Trunc.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Trunc.java
index b052598fc76904972ba2d5e71940f9b38212181f..3d0e13e8a458fc6d6d11fbe93943b603e41c7ff3 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Trunc.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Trunc.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -22,6 +22,8 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.complexValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
 import static com.oracle.truffle.r.runtime.RDispatch.MATH_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -29,6 +31,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNode;
 import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNode;
 import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen;
@@ -45,6 +48,18 @@ public abstract class Trunc extends RBuiltinNode {
     @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create();
     @Child private UnaryArithmeticNode trunc = UnaryArithmeticNodeGen.create(TRUNC, RError.Message.NON_NUMERIC_MATH, RType.Double);
 
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        //@formatter:off
+        casts.arg("x").
+            defaultError(this, RError.Message.NON_NUMERIC_MATH).
+            mustNotBeNull().
+            mustBe(complexValue().not(), RError.Message.UNIMPLEMENTED_COMPLEX_FUN).
+            mustBe(numericValue()).
+            asDoubleVector(true, true, true);
+        //@formatter:on
+    }
+
     @Specialization
     protected Object trunc(Object value) {
         return trunc.execute(boxPrimitive.execute(value));
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyScalarNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyScalarNode.java
index 2c1c4fc4c9628d000232d5e827a479ff00aeae75..8f47695a8a26ace0fbaad53e9cd6a8537e597eb2 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyScalarNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyScalarNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -22,8 +22,14 @@
  */
 package com.oracle.truffle.r.nodes.function;
 
+import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.r.nodes.unary.UnaryNode;
+import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.data.RAttributable;
+import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.RStringVector;
 
 public abstract class ClassHierarchyScalarNode extends UnaryNode {
 
@@ -35,4 +41,19 @@ public abstract class ClassHierarchyScalarNode extends UnaryNode {
     protected String getClassHr(Object arg) {
         return classHierarchyNode.execute(arg).getDataAt(0);
     }
+
+    public static String get(Object arg) {
+        CompilerAsserts.neverPartOfCompilation();
+
+        Object v = RRuntime.asAbstractVector(arg);
+        if (v instanceof RAttributable) {
+            RStringVector classHierarchy = ((RAttributable) v).getClassHierarchy();
+            return classHierarchy.getLength() == 0 ? "" : classHierarchy.getDataAt(0);
+        } else if (arg == RNull.instance) {
+            return "NULL";
+        } else {
+            assert arg instanceof TruffleObject;
+            return "";
+        }
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index a8c731af313af7e61406addaeda0c66f6c69e277..f17543e5fe71799d5a31af8e1a7c21922d2e7ca1 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -12458,6 +12458,14 @@ c 2
 #{ ceiling(c(0.2,-3.4,NA,0/0,1/0)) }
 [1]   1  -3  NA NaN Inf
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_ceiling.testCeiling#
+#{ trunc("aaa"); }
+Error in trunc("aaa") : non-numeric argument to mathematical function
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_ceiling.testCeiling#
+#{ trunc(1+1i); }
+Error in trunc(1 + (0+1i)) : unimplemented complex function
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_ceiling.testCeiling#
 #{ typeof(ceiling(42L)); }
 [1] "double"
@@ -20735,6 +20743,14 @@ Error: 4 arguments passed to .Internal(findInterval) which requires 5
 #{ floor(c(0.2,-3.4,NA,0/0,1/0)) }
 [1]   0  -4  NA NaN Inf
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_floor.testFloor#
+#{ trunc("aaa"); }
+Error in trunc("aaa") : non-numeric argument to mathematical function
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_floor.testFloor#
+#{ trunc(1+1i); }
+Error in trunc(1 + (0+1i)) : unimplemented complex function
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_floor.testFloor#
 #{ typeof(floor(42L)); }
 [1] "double"
@@ -43636,6 +43652,10 @@ Error in rm(tmp, inherits = "asd") : invalid 'inherits' argument
 #{ round(0.6) }
 [1] 1
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_round.testRound#Ignored.Unimplemented#
+#{ round(1.1234+1i, 3.1+1i); }
+[1] 1.123+1i
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_round.testRound#Ignored.Unknown#
 #{ round(1.123456,digit=2.8) }
 [1] 1.123
@@ -64800,6 +64820,14 @@ tracemem[0x7f818486bc90 -> 0x7f818486ba50]:
 [66]   0.46780689   0.44721207   0.42833216   0.41096375   0.39493407
 [71]   0.21654883   0.01307171
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_trunc.testTrunc#
+#{ trunc("aaa"); }
+Error in trunc("aaa") : non-numeric argument to mathematical function
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_trunc.testTrunc#
+#{ trunc(1+1i); }
+Error in trunc(1 + (0+1i)) : unimplemented complex function
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_trunc.testTrunc#
 #{ typeof(trunc(42L)); }
 [1] "double"
@@ -130357,6 +130385,18 @@ Error: use of NULL environment is defunct
 #.Call(methods:::C_R_getClassFromCache, "aaa", new.env())
 NULL
 
+##com.oracle.truffle.r.test.library.stats.TestExternal_R_getGeneric.testGetPrimName#
+#.Call(methods:::C_R_getGeneric,"aaa",TRUE,new.env(),"bbb")
+Error: no generic function definition found for 'aaa' in the supplied environment
+
+##com.oracle.truffle.r.test.library.stats.TestExternal_R_getGeneric.testGetPrimName#
+#.Call(methods:::C_R_getGeneric,"aaa",TRUE,new.env(),NULL)
+Error: 'The argument "package" to getGeneric' must be a single string (got an object of class "NULL")
+
+##com.oracle.truffle.r.test.library.stats.TestExternal_R_getGeneric.testGetPrimName#
+#.Call(methods:::C_R_getGeneric,NULL,TRUE,new.env(),"bbb")
+Error: 'The argument "f" to getGeneric' must be a single string (got an object of class "NULL")
+
 ##com.oracle.truffle.r.test.library.stats.TestExternal_R_getSlot.testGetPrimName#
 #.Call(methods:::C_R_get_slot,"","")
 Error: attempt to use zero-length variable name
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ceiling.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ceiling.java
index 6ee6a89326e81f908bf5bc5a7e0b265d6bab25a5..a9b34b32a401376b65596567f2a082dddabb4930 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ceiling.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ceiling.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2012-2014, Purdue University
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -62,5 +62,7 @@ public class TestBuiltin_ceiling extends TestBase {
         assertEval("{ ceiling(c(0.2,-3.4,NA,0/0,1/0)) }");
         assertEval("{ typeof(ceiling(42L)); }");
         assertEval("{ typeof(ceiling(TRUE)); }");
+        assertEval("{ trunc(1+1i); }");
+        assertEval("{ trunc(\"aaa\"); }");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_floor.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_floor.java
index 8d8199389e5dac51f8c16d73c241b098c68a15a9..39355fc4872fbb9ec404f8c1c343e6f0902ccf57 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_floor.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_floor.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2012-2014, Purdue University
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -67,5 +67,7 @@ public class TestBuiltin_floor extends TestBase {
         assertEval("{ floor(c(0.2,-3.4,NA,0/0,1/0)) }");
         assertEval("{ typeof(floor(42L)); }");
         assertEval("{ typeof(floor(TRUE)); }");
+        assertEval("{ trunc(1+1i); }");
+        assertEval("{ trunc(\"aaa\"); }");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_round.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_round.java
index 29dfc5c56e319099433b8ebf7b73f78c95476dcb..ca06cd1db769155a7350fb0106f79e861e9ca35f 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_round.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_round.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2012-2014, Purdue University
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -52,5 +52,7 @@ public class TestBuiltin_round extends TestBase {
 
         assertEval("{ typeof(round(42L)); }");
         assertEval("{ typeof(round(TRUE)); }");
+
+        assertEval(Ignored.Unimplemented, "{ round(1.1234+1i, 3.1+1i); }");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_trunc.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_trunc.java
index b901f82f72fc766a1029ebe03c64e16440d8159e..f2080c629791428866d06c5d55d58a8be498e3ed 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_trunc.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_trunc.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -41,5 +41,7 @@ public class TestBuiltin_trunc extends TestBase {
     public void testTrunc() {
         assertEval("{ typeof(trunc(42L)); }");
         assertEval("{ typeof(trunc(TRUE)); }");
+        assertEval("{ trunc(1+1i); }");
+        assertEval("{ trunc(\"aaa\"); }");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_R_getGeneric.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_R_getGeneric.java
new file mode 100644
index 0000000000000000000000000000000000000000..ebf214c9c10ee4cb36f5e4cd88c5ba409ed29657
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_R_getGeneric.java
@@ -0,0 +1,37 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.truffle.r.test.library.stats;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+public class TestExternal_R_getGeneric extends TestBase {
+    @Test
+    public void testGetPrimName() {
+        assertEval(".Call(methods:::C_R_getGeneric,\"aaa\",TRUE,new.env(),\"bbb\")");
+        assertEval(".Call(methods:::C_R_getGeneric,NULL,TRUE,new.env(),\"bbb\")");
+        assertEval(".Call(methods:::C_R_getGeneric,\"aaa\",TRUE,new.env(),NULL)");
+    }
+}