diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsFiniteFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsFiniteFunctions.java
index 075d0dbb0345c8a8fbb981fac42b4732aa436adb..501d4a283f10f8a9cddbee1d34879ff4cc9c8de8 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsFiniteFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsFiniteFunctions.java
@@ -31,7 +31,9 @@ import java.util.function.IntPredicate;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Fallback;
+import com.oracle.truffle.api.dsl.ImportStatic;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -53,6 +55,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
 public class IsFiniteFunctions {
 
+    @ImportStatic(RRuntime.class)
     public abstract static class Adapter extends RBuiltinNode.Arg1 {
 
         @Child private GetDimAttributeNode getDims = GetDimAttributeNode.create();
@@ -83,6 +86,12 @@ public class IsFiniteFunctions {
             return doFunConstant(x, RRuntime.LOGICAL_FALSE);
         }
 
+        @Specialization(guards = "isForeignObject(obj)")
+        @TruffleBoundary
+        protected byte doIsForeign(@SuppressWarnings("unused") TruffleObject obj) {
+            throw error(RError.Message.DEFAULT_METHOD_NOT_IMPLEMENTED_FOR_TYPE, "external object");
+        }
+
         @Fallback
         @TruffleBoundary
         protected Object doIsFiniteOther(Object x) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java
index c08de1b1f10abdba38904bb6e90c461d64b64727..166728e6642771dc131f3944539d2638e4ad2bc0 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java
@@ -29,7 +29,9 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Fallback;
+import com.oracle.truffle.api.dsl.ImportStatic;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode;
@@ -53,6 +55,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
+@ImportStatic(RRuntime.class)
 @RBuiltin(name = "is.na", kind = PRIMITIVE, parameterNames = {"x"}, dispatch = INTERNAL_GENERIC, behavior = PURE)
 public abstract class IsNA extends RBuiltinNode.Arg1 {
 
@@ -195,6 +198,11 @@ public abstract class IsNA extends RBuiltinNode.Arg1 {
         return RDataFactory.createEmptyLogicalVector();
     }
 
+    @Specialization(guards = "isForeignObject(obj)")
+    protected byte isNA(@SuppressWarnings("unused") TruffleObject obj) {
+        return RRuntime.LOGICAL_FALSE;
+    }
+
     // Note: all the primitive values have specialization, so we can only get RTypedValue in
     // fallback
     @Fallback
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java
index 74152f23bf2199922819321a77e4e70350476f6c..f966c9ab3c357134731cfa5fa331f6379f3c94ce 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java
@@ -31,7 +31,9 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
+import com.oracle.truffle.api.dsl.ImportStatic;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode;
@@ -100,6 +102,7 @@ public class IsTypeFunctions {
         }
     }
 
+    @ImportStatic(RRuntime.class)
     @RBuiltin(name = "is.recursive", kind = PRIMITIVE, parameterNames = {"x"}, behavior = PURE)
     public abstract static class IsRecursive extends MissingAdapter {
 
@@ -126,6 +129,11 @@ public class IsTypeFunctions {
             return arg instanceof RListBase;
         }
 
+        @Specialization(guards = "isForeignObject(obj)")
+        protected byte isRecursive(@SuppressWarnings("unused") TruffleObject obj) {
+            return RRuntime.LOGICAL_FALSE;
+        }
+
         @Fallback
         protected byte isRecursiveFallback(@SuppressWarnings("unused") Object value) {
             return RRuntime.LOGICAL_TRUE;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/TypeofNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/TypeofNode.java
index 1df443ba8c97ea0df8b9b11c2f42a9540d0b1608..c2e606b1f73a542fce854d221e417ee5848b8d36 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/TypeofNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/TypeofNode.java
@@ -62,6 +62,11 @@ public abstract class TypeofNode extends UnaryNode {
         return RType.Missing;
     }
 
+    @Specialization(guards = "isForeignObject(object)")
+    protected RType doTruffleObject(@SuppressWarnings("unused") TruffleObject object) {
+        return RType.TruffleObject;
+    }
+
     @Specialization(guards = {"operand.getClass() == cachedClass"}, limit = "NUMBER_OF_CACHED_CLASSES")
     protected static RType doCachedTyped(Object operand,
                     @Cached("getTypedValueClass(operand)") Class<? extends RTypedValue> cachedClass) {
@@ -82,11 +87,6 @@ public abstract class TypeofNode extends UnaryNode {
         return operand.getRType();
     }
 
-    @Specialization(guards = "isForeignObject(object)")
-    protected RType doTruffleObject(@SuppressWarnings("unused") TruffleObject object) {
-        return RType.TruffleObject;
-    }
-
     protected static boolean isForeignObject(Object obj) {
         return RRuntime.isForeignObject(obj);
     }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java
index f9852832d2f60e5024c9e54cda373f4d034e6794..dd2d584e5b43bf6515adab3e789d6798ae427c13 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java
@@ -329,7 +329,7 @@ public class TestJavaInterop extends TestBase {
     }
 
     @Test
-    public void testNamesForJavaObject() {
+    public void testNamesForForeignObject() {
         assertEvalFastR("tc <- .fastr.java.class('" + TestNamesClassNoMembers.class.getName() + "'); t <- .fastr.interop.new(tc); names(t)", "NULL");
         assertEvalFastR("tc <- .fastr.java.class('" + TestNamesClassNoPublicMembers.class.getName() + "'); t <- .fastr.interop.new(tc); names(t)", "NULL");
         assertEvalFastR("tc <- .fastr.java.class('" + TestNamesClass.class.getName() + "'); sort(names(tc))", "c('staticField', 'staticMethod')");
@@ -340,6 +340,63 @@ public class TestJavaInterop extends TestBase {
         assertEvalFastR("tc <- .fastr.java.class('" + TestNamesClassMap.class.getName() + "'); t <- .fastr.interop.new(tc); sort(names(t$m()))", "c('one', 'two')");
     }
 
+    @Test
+    public void testIsXXXForForeignObject() {
+        // missing: is.element, is.empty.model, is.leaf, is.loaded, is.na.data.frame,
+        // is.na.numeric_version, is.na.POSIXlt
+
+        assertPassingForeighObjectToFunction("is.array", "FALSE");
+        assertPassingForeighObjectToFunction("is.atomic", "FALSE");
+        assertPassingForeighObjectToFunction("is.call", "FALSE");
+        assertPassingForeighObjectToFunction("is.character", "FALSE");
+        assertPassingForeighObjectToFunction("is.complex", "FALSE");
+        assertPassingForeighObjectToFunction("is.data.frame", "FALSE");
+        assertPassingForeighObjectToFunction("is.double", "FALSE");
+        assertPassingForeighObjectToFunction("is.environment", "FALSE");
+        assertPassingForeighObjectToFunction("is.expression", "FALSE");
+        assertPassingForeighObjectToFunction("is.factor", "FALSE");
+        assertPassingForeighObjectToFunction("is.function", "FALSE");
+        assertPassingForeighObjectToFunction("is.integer", "FALSE");
+        assertPassingForeighObjectToFunction("is.language", "FALSE");
+        assertPassingForeighObjectToFunction("is.logical", "FALSE");
+        assertPassingForeighObjectToFunction("is.matrix", "FALSE");
+        assertPassingForeighObjectToFunction("is.mts", "FALSE");
+        assertPassingForeighObjectToFunction("is.na", "FALSE");
+        assertPassingForeighObjectToFunction("is.name", "FALSE");
+        assertPassingForeighObjectToFunction("is.null", "FALSE");
+        assertPassingForeighObjectToFunction("is.numeric", "FALSE");
+        assertPassingForeighObjectToFunction("is.numeric.Date", "FALSE");
+        assertPassingForeighObjectToFunction("is.numeric.difftime", "FALSE");
+        assertPassingForeighObjectToFunction("is.numeric.POSIXt", "FALSE");
+        assertPassingForeighObjectToFunction("is.numeric_version", "FALSE");
+        assertPassingForeighObjectToFunction("is.object", "FALSE");
+        assertPassingForeighObjectToFunction("is.ordered", "FALSE");
+        assertPassingForeighObjectToFunction("is.package_version", "FALSE");
+        assertPassingForeighObjectToFunction("is.pairlist", "FALSE");
+        assertPassingForeighObjectToFunction("is.primitive", "FALSE");
+        assertPassingForeighObjectToFunction("is.qr", "FALSE");
+        assertPassingForeighObjectToFunction("is.raster", "FALSE");
+        assertPassingForeighObjectToFunction("is.raw", "FALSE");
+        assertPassingForeighObjectToFunction("is.recursive", "FALSE");
+        assertPassingForeighObjectToFunction("is.relistable", "FALSE");
+        assertPassingForeighObjectToFunction("is.stepfun", "FALSE");
+        assertPassingForeighObjectToFunction("is.symbol", "FALSE");
+        assertPassingForeighObjectToFunction("is.table", "FALSE");
+        assertPassingForeighObjectToFunction("is.ts", "FALSE");
+        assertPassingForeighObjectToFunction("is.tskernel", "FALSE");
+        assertPassingForeighObjectToFunction("is.unsorted", "FALSE");
+        assertPassingForeighObjectToFunction("is.vector", "FALSE");
+
+        assertPassingForeighObjectToFunction("is.nan", "cat('Error in is.nan(to) : ', '\n', '  default method not implemented for type \\'external object\\'\n', sep='')");
+        assertPassingForeighObjectToFunction("is.finite", "cat('Error in is.finite(to) : ', '\n', '  default method not implemented for type \\'external object\\'\n', sep='')");
+        assertPassingForeighObjectToFunction("is.infinite", "cat('Error in is.infinite(to) : ', '\n', '  default method not implemented for type \\'external object\\'\n', sep='')");
+
+    }
+
+    private void assertPassingForeighObjectToFunction(String function, String expectedOutput) {
+        assertEvalFastR("to <- .fastr.interop.new(.fastr.java.class('" + TEST_CLASS + "')); " + function + "(to)", expectedOutput);
+    }
+
     @Test
     public void testAttributes() {
         assertEvalFastR("to <- .fastr.interop.new(.fastr.java.class('" + TEST_CLASS + "')); attributes(to)", "NULL");