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 9fbc99886e15a80afb408dab067cabdf1ea63e59..8ea54305d44ca160b38b920c4a3218e829220f40 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
@@ -85,6 +85,7 @@ import com.oracle.truffle.r.runtime.VirtualEvalFrame;
 import com.oracle.truffle.r.runtime.context.Engine;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
+import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RFunction;
@@ -99,6 +100,7 @@ import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
+import com.oracle.truffle.r.runtime.nodes.RCodeBuilder;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxElement;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
@@ -594,13 +596,19 @@ final class REngine implements Engine, Engine.Timings {
         result = RRuntime.asAbstractVector(result);
         if (result instanceof RTypedValue || result instanceof TruffleObject) {
             Object resultValue = evaluatePromise(result);
-            Object printMethod = REnvironment.globalEnv().findFunction("print");
-            RFunction function = (RFunction) evaluatePromise(printMethod);
             if (resultValue instanceof RShareable && !((RShareable) resultValue).isSharedPermanent()) {
                 ((RShareable) resultValue).incRefCount();
             }
             MaterializedFrame callingFrame = REnvironment.globalEnv().getFrame();
-            CallRFunctionNode.executeSlowpath(function, RCaller.createInvalid(callingFrame), callingFrame, new Object[]{resultValue, RMissing.instance}, null);
+            if (result instanceof RAttributable && ((RAttributable) result).isS4()) {
+                Object printMethod = REnvironment.getRegisteredNamespace("methods").get("show");
+                RFunction function = (RFunction) evaluatePromise(printMethod);
+                CallRFunctionNode.executeSlowpath(function, RCaller.createInvalid(callingFrame), callingFrame, new Object[]{resultValue}, null);
+            } else {
+                Object printMethod = REnvironment.globalEnv().findFunction("print");
+                RFunction function = (RFunction) evaluatePromise(printMethod);
+                CallRFunctionNode.executeSlowpath(function, RCaller.createInvalid(callingFrame), callingFrame, new Object[]{resultValue, RMissing.instance}, null);
+            }
             if (resultValue instanceof RShareable && !((RShareable) resultValue).isSharedPermanent()) {
                 ((RShareable) resultValue).decRefCount();
             }
@@ -610,6 +618,27 @@ final class REngine implements Engine, Engine.Timings {
         }
     }
 
+    /*
+     * This abstracts the calling convention, etc. behind the RASTBuilder, but creating large
+     * amounts of CallTargets during testing is too much overhead at the moment.
+     */
+    @SuppressWarnings("unused")
+    private void printAlternative(Object result) {
+        Object printFunction;
+        if (result instanceof RAttributable && ((RAttributable) result).isS4()) {
+            printFunction = REnvironment.getRegisteredNamespace("methods").get("show");
+        } else {
+            printFunction = REnvironment.getRegisteredNamespace("base").get("print");
+        }
+        RFunction function = (RFunction) evaluatePromise(printFunction);
+
+        MaterializedFrame callingFrame = REnvironment.globalEnv().getFrame();
+        // create a piece of AST to perform the call
+        RCodeBuilder<RSyntaxNode> builder = RContext.getASTBuilder();
+        RSyntaxNode call = builder.call(RSyntaxNode.LAZY_DEPARSE, builder.constant(RSyntaxNode.LAZY_DEPARSE, function), builder.constant(RSyntaxNode.LAZY_DEPARSE, result));
+        doMakeCallTarget(call.asRNode(), RSource.Internal.EVAL_WRAPPER.string, false, false).call(callingFrame);
+    }
+
     private static String toString(Object originalResult) {
         Object result = evaluatePromise(originalResult);
         result = RRuntime.asAbstractVector(result);
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_setS4Object.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_setS4Object.java
index eeb9eae3cee9a745ea131db97efcf185b99ab545..6e97897494f4ef361aa6fb24f55a7d6abcbcaa7e 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_setS4Object.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_setS4Object.java
@@ -43,8 +43,7 @@ public class TestBuiltin_setS4Object extends TestBase {
 
     @Test
     public void testsetS4Object5() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(structure(c('nonStructure', 'ANY', 'ANY', 'ANY'), .Names = c(NA_character_, NA_character_, NA_character_, NA_character_), package = character(0), class = structure('signature', package = 'methods')), TRUE, 0L); .Internal(setS4Object(argv[[1]], argv[[2]], argv[[3]]))");
+        assertEval("argv <- list(structure(c('nonStructure', 'ANY', 'ANY', 'ANY'), .Names = c(NA_character_, NA_character_, NA_character_, NA_character_), package = character(0), class = structure('signature', package = 'methods')), TRUE, 0L); .Internal(setS4Object(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestMiscBuiltins.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestMiscBuiltins.java
index 20799e15560ddbacd8e4ba9d6909ade207729891..83b5944db3f68f4e5f3b6946121656056a36ab44 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestMiscBuiltins.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestMiscBuiltins.java
@@ -144,19 +144,14 @@ public class TestMiscBuiltins extends TestBase {
         assertEval("{ m <- { matrix( as.raw(11:16), nrow=2 ) } ; diag(m) <- c(as.raw(1),as.raw(2)) ; m }");
     }
 
-    //@formatter:off
     private static final String[] BASIC_TYPES = new String[]{
-        "call", "character", "complex", "double", "expression", "function", "integer", "list",
-        "logical", "name", "symbol", "null", "pairlist", "raw",
+                    "call", "character", "complex", "double", "expression", "function", "integer", "list", "logical", "name", "symbol", "null", "pairlist", "raw",
     };
 
     private static final String[] BASIC_TYPE_VALUES = new String[]{
-        "call(\"foo\")", "\"1\"", "1i", "1", "expression(x + 1)", "function() { }",
-        "1L", "list()", "TRUE", "quote(x)", "NULL", "pairlist()", "raw()"
+                    "call(\"foo\")", "\"1\"", "1i", "1", "expression(x + 1)", "function() { }", "1L", "list()", "TRUE", "quote(x)", "NULL", "pairlist()", "raw()"
     };
 
-    //@formatter:on
-
     @Test
     public void testBasicTypes() {
         // cross-product of all basic types and values