From 6201ca83e8e2174efbafb01f128ad333e94052ff Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Fri, 10 Feb 2017 16:43:48 +0100
Subject: [PATCH] Implement Rf_coerceVector as upcall

---
 .../fficall/src/common/coerce_fastr.c         | 117 ---
 .../fficall/src/jni/Rinternals.c              |   9 +
 .../truffle/r/nodes/ffi/CoerceVectorNode.java | 168 ++++
 .../r/nodes/ffi/FFIUpCallRootNode.java        |   1 +
 .../r/nodes/ffi/JavaUpCallsRFFIImpl.java      |   5 +
 .../truffle/r/nodes/ffi/RFFIUpCallMethod.java |   1 +
 .../r/nodes/ffi/TracingUpCallsRFFIImpl.java   |   6 +
 .../truffle/r/runtime/ffi/StdUpCallsRFFI.java |   2 +
 .../packages/testrffi/testrffi/R/testrffi.R   |   3 +
 .../packages/testrffi/testrffi/src/init.c     |  67 +-
 .../packages/testrffi/testrffi/src/testrffi.c |   6 +
 .../packages/testrffi/testrffi/src/testrffi.h |   2 +
 .../truffle/r/test/ExpectedTestOutput.test    | 789 ++++++++++++++++++
 .../r/test/rffi/TestRFFIPackageCoercions.java |  90 ++
 .../r/test/rpackages/TestRPackages.java       |   5 +
 15 files changed, 1121 insertions(+), 150 deletions(-)
 create mode 100644 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/CoerceVectorNode.java
 create mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackageCoercions.java

diff --git a/com.oracle.truffle.r.native/fficall/src/common/coerce_fastr.c b/com.oracle.truffle.r.native/fficall/src/common/coerce_fastr.c
index 2e0b2fe4c5..764b8be1bb 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/coerce_fastr.c
+++ b/com.oracle.truffle.r.native/fficall/src/common/coerce_fastr.c
@@ -308,120 +308,3 @@ static SEXP coercePairList(SEXP v, SEXPTYPE type)
     return rval;
 }
 
-SEXP Rf_coerceVector(SEXP v, SEXPTYPE type)
-{
-    SEXP op, vp, ans = R_NilValue;	/* -Wall */
-    int i,n;
-
-    if (TYPEOF(v) == type)
-	return v;
-    /* code to allow classes to extend ENVSXP, SYMSXP, etc */
-    if(IS_S4_OBJECT(v) && TYPEOF(v) == S4SXP) {
-	SEXP vv = R_getS4DataSlot(v, ANYSXP);
-	if(vv == R_NilValue)
-	  error(_("no method for coercing this S4 class to a vector"));
-	else if(TYPEOF(vv) == type)
-	  return vv;
-	v = vv;
-    }
-
-    switch (TYPEOF(v)) {
-#ifdef NOTYET
-    case NILSXP:
-	ans = coerceNull(v, type);
-	break;
-#endif
-    case SYMSXP:
-	ans = coerceSymbol(v, type);
-	break;
-    case NILSXP:
-    case LISTSXP:
-	ans = coercePairList(v, type);
-	break;
-    case LANGSXP:
-	if (type != STRSXP) {
-	    ans = coercePairList(v, type);
-	    break;
-	}
-
-	/* This is mostly copied from coercePairList, but we need to
-	 * special-case the first element so as not to get operators
-	 * put in backticks. */
-	n = length(v);
-	PROTECT(ans = allocVector(type, n));
-	if (n == 0) break; /* Can this actually happen? */
-	i = 0;
-	op = CAR(v);
-	/* The case of practical relevance is "lhs ~ rhs", which
-	 * people tend to split using as.character(), modify, and
-	 * paste() back together. However, we might as well
-	 * special-case all symbolic operators here. */
-	if (TYPEOF(op) == SYMSXP) {
-	    SET_STRING_ELT(ans, i, PRINTNAME(op));
-	    i++;
-	    v = CDR(v);
-	}
-
-	/* The distinction between strings and other elements was
-	 * here "always", but is really dubious since it makes x <- a
-	 * and x <- "a" come out identical. Won't fix just now. */
-	for (vp = v;  vp != R_NilValue; vp = CDR(vp), i++) {
-	    if (isString(CAR(vp)) && length(CAR(vp)) == 1)
-		SET_STRING_ELT(ans, i, STRING_ELT(CAR(vp), 0));
-	    else
-		SET_STRING_ELT(ans, i, STRING_ELT(deparse1line(CAR(vp), 0), 0));
-	}
-	UNPROTECT(1);
-	break;
-    case VECSXP:
-    case EXPRSXP:
-	ans = coerceVectorList(v, type);
-	break;
-    case ENVSXP:
-	error(_("environments cannot be coerced to other types"));
-	break;
-    case LGLSXP:
-    case INTSXP:
-    case REALSXP:
-    case CPLXSXP:
-    case STRSXP:
-    case RAWSXP:
-
-#define COERCE_ERROR_STRING "cannot coerce type '%s' to vector of type '%s'"
-
-#define COERCE_ERROR							\
-	error(_(COERCE_ERROR_STRING), type2char(TYPEOF(v)), type2char(type))
-
-	switch (type) {
-	case SYMSXP:
-	    ans = coerceToSymbol(v);	    break;
-	case LGLSXP:
-	    ans = coerceToLogical(v);	    break;
-	case INTSXP:
-	    ans = coerceToInteger(v);	    break;
-	case REALSXP:
-	    ans = coerceToReal(v);	    break;
-	case CPLXSXP:
-	    ans = coerceToComplex(v);	    break;
-	case RAWSXP:
-	    ans = coerceToRaw(v);	    break;
-	case STRSXP:
-	    ans = coerceToString(v);	    break;
-	case EXPRSXP:
-	    ans = coerceToExpression(v);    break;
-	case VECSXP:
-	    ans = coerceToVectorList(v);    break;
-	case LISTSXP:
-	    ans = coerceToPairList(v);	    break;
-	default:
-	    COERCE_ERROR;
-	}
-	break;
-    default:
-	COERCE_ERROR;
-    }
-    return ans;
-}
-#undef COERCE_ERROR
-
-
diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
index 7091886c83..affaab5f72 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
@@ -92,6 +92,7 @@ static jmethodID LENGTH_MethodID;
 static jmethodID Rf_asIntegerMethodID;
 static jmethodID Rf_asRealMethodID;
 static jmethodID Rf_asCharMethodID;
+static jmethodID Rf_coerceVectorMethodID;
 static jmethodID Rf_mkCharLenCEMethodID;
 static jmethodID Rf_asLogicalMethodID;
 static jmethodID Rf_PairToVectorListMethodID;
@@ -203,6 +204,7 @@ void init_internals(JNIEnv *env) {
 	Rf_asRealMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_asReal", "(Ljava/lang/Object;)D", 0);
 	Rf_asCharMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_asChar", "(Ljava/lang/Object;)Ljava/lang/Object;", 0);
 	Rf_mkCharLenCEMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_mkCharLenCE", "(Ljava/lang/Object;II)Ljava/lang/Object;", 0);
+        Rf_coerceVectorMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_coerceVector", "(Ljava/lang/Object;I)Ljava/lang/Object;", 0);
 	Rf_asLogicalMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_asLogical", "(Ljava/lang/Object;)I", 0);
 	Rf_PairToVectorListMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_PairToVectorList", "(Ljava/lang/Object;)Ljava/lang/Object;", 0);
 	NAMED_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "NAMED", "(Ljava/lang/Object;)I", 0);
@@ -1230,6 +1232,13 @@ SEXP Rf_asChar(SEXP x){
 	return checkRef(thisenv, result);
 }
 
+SEXP Rf_coerceVector(SEXP x, SEXPTYPE mode){
+	TRACE(TARGp, x);
+	JNIEnv *thisenv = getEnv();
+	SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_coerceVectorMethodID, x, mode);
+	return checkRef(thisenv, result);
+}
+
 SEXP Rf_PairToVectorList(SEXP x){
 	TRACE(TARGp, x);
 	JNIEnv *thisenv = getEnv();
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/CoerceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/CoerceVectorNode.java
new file mode 100644
index 0000000000..b7eb9d97d3
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/CoerceVectorNode.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 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.nodes.ffi;
+
+import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.unimplemented;
+
+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.Specialization;
+import com.oracle.truffle.r.nodes.unary.CastComplexNode;
+import com.oracle.truffle.r.nodes.unary.CastDoubleNode;
+import com.oracle.truffle.r.nodes.unary.CastExpressionNode;
+import com.oracle.truffle.r.nodes.unary.CastIntegerNode;
+import com.oracle.truffle.r.nodes.unary.CastListNode;
+import com.oracle.truffle.r.nodes.unary.CastLogicalNode;
+import com.oracle.truffle.r.nodes.unary.CastNode;
+import com.oracle.truffle.r.nodes.unary.CastRawNode;
+import com.oracle.truffle.r.nodes.unary.CastStringNode;
+import com.oracle.truffle.r.nodes.unary.CastSymbolNode;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RTypedValue;
+import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
+
+/**
+ * Implements Rf_coerceVector.
+ */
+public abstract class CoerceVectorNode extends FFIUpCallNode.Arg2 {
+
+    public static CoerceVectorNode create() {
+        return CoerceVectorNodeGen.create();
+    }
+
+    @Specialization(guards = "value.isS4()")
+    Object doS4Object(RTypedValue value, int mode) {
+        throw RError.nyi(RError.NO_CALLER, "Rf_coerceVector for S4 objects.");
+    }
+
+    // Note: caches should cover all valid possibilities
+    @Specialization(guards = {"!isS4Object(value)", "isNotList(value)", "isValidMode(mode)", "cachedMode == mode"}, limit = "99")
+    Object doCached(Object value, int mode,
+                    @Cached("mode") int cachedMode,
+                    @Cached("createCastNode(cachedMode)") CastNode castNode) {
+        return castNode.execute(value);
+    }
+
+    // Lists are coerced with only preserved names unlike other types
+    @Specialization(guards = {"!isS4Object(value)", "isValidMode(mode)", "cachedMode == mode"}, limit = "99")
+    Object doCached(RList value, int mode,
+                    @Cached("mode") int cachedMode,
+                    @Cached("createCastNodeForList(cachedMode)") CastNode castNode) {
+        return castNode.execute(value);
+    }
+
+    @Fallback
+    @TruffleBoundary
+    Object doFallback(Object value, Object mode) {
+        String type = value != null ? value.getClass().getSimpleName() : "null";
+        throw unimplemented(String.format("Rf_coerceVector unimplemented for type %s or mode %s.", type, mode));
+    }
+
+    static boolean isS4Object(Object obj) {
+        return obj instanceof RTypedValue && ((RTypedValue) obj).isS4();
+    }
+
+    static boolean isNotList(Object obj) {
+        return !(obj instanceof RList);
+    }
+
+    static boolean isValidMode(int mode) {
+        return mode >= SEXPTYPE.NILSXP.code && mode <= SEXPTYPE.RAWSXP.code;
+    }
+
+    static CastNode createCastNode(int mode) {
+        return createCastNode(mode, false);
+    }
+
+    static CastNode createCastNodeForList(int mode) {
+        return createCastNode(mode, true);
+    }
+
+    private static CastNode createCastNode(int mode, boolean forList) {
+        SEXPTYPE type = SEXPTYPE.mapInt(mode);
+        boolean preserveDims = !forList;
+        boolean preserveAttrs = !forList;
+        switch (type) {
+            case SYMSXP:
+                return CastSymbolNode.createForRFFI(false, false, false);
+            case NILSXP:
+                return new CastNullNode();
+            case LISTSXP:
+                throw unimplemented("Rf_coerceVector called with unimplemented for PairLists.");
+            case LANGSXP:
+                throw unimplemented("Rf_coerceVector called with unimplemented for RLanguage.");
+            case ENVSXP:
+                return new EnvironmentCast();
+            case VECSXP:
+                return CastListNode.createForRFFI(true, forList, forList);
+            case EXPRSXP:
+                return CastExpressionNode.createForRFFI(false, false, false);
+            case INTSXP:
+                return CastIntegerNode.createForRFFI(true, preserveDims, preserveAttrs);
+            case REALSXP:
+                return CastDoubleNode.createForRFFI(true, preserveDims, preserveAttrs);
+            case LGLSXP:
+                return CastLogicalNode.createForRFFI(true, preserveDims, preserveAttrs);
+            case STRSXP:
+                return CastStringNode.createForRFFI(true, preserveDims, preserveAttrs);
+            case CPLXSXP:
+                return CastComplexNode.createForRFFI(true, preserveDims, preserveAttrs);
+            case RAWSXP:
+                return CastRawNode.createForRFFI(true, preserveDims, preserveAttrs);
+            default:
+                throw unimplemented(String.format("Rf_coerceVector called with unimplemented mode %d (type %s).", mode, type));
+        }
+    }
+
+    private static final class CastNullNode extends CastNode {
+        @Override
+        @TruffleBoundary
+        public Object execute(@SuppressWarnings("unused") Object value) {
+            if (value instanceof RList) {
+                throw RError.error(RError.NO_CALLER, Message.UNIMPLEMENTED_TYPE_IN_FUNCTION, "list", "coerceVectorList");
+            } else {
+                throw RError.error(RError.NO_CALLER, Message.CANNOT_COERCE, getTypeName(value), "NULL");
+            }
+        }
+
+        private static String getTypeName(Object val) {
+            Object value = RRuntime.asAbstractVector(val);
+            if (value == null) {
+                return "null";
+            }
+            return value instanceof RTypedValue ? ((RTypedValue) value).getRType().getName() : value.getClass().getSimpleName();
+        }
+    }
+
+    private static final class EnvironmentCast extends CastNode {
+        @Override
+        @TruffleBoundary
+        public Object execute(Object value) {
+            throw RError.error(RError.NO_CALLER, Message.ENVIRONMENTS_COERCE);
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/FFIUpCallRootNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/FFIUpCallRootNode.java
index 6cd1f9fe0e..e7d26f933b 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/FFIUpCallRootNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/FFIUpCallRootNode.java
@@ -84,6 +84,7 @@ public final class FFIUpCallRootNode extends RootNode {
         FFIUpCallRootNode.add(RFFIUpCallMethod.Rf_asLogical, AsLogicalNodeGen::create);
         FFIUpCallRootNode.add(RFFIUpCallMethod.Rf_asInteger, AsIntegerNodeGen::create);
         FFIUpCallRootNode.add(RFFIUpCallMethod.Rf_asChar, AsCharNodeGen::create);
+        FFIUpCallRootNode.add(RFFIUpCallMethod.Rf_coerceVector, CoerceVectorNode::create);
         FFIUpCallRootNode.add(RFFIUpCallMethod.CAR, CARNodeGen::create);
         FFIUpCallRootNode.add(RFFIUpCallMethod.CDR, CDRNodeGen::create);
         FFIUpCallRootNode.add(RFFIUpCallMethod.CADR, CADRNodeGen::create);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java
index 03d4150564..a12d923fd9 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java
@@ -156,6 +156,11 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
         return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.Rf_asChar).call(x);
     }
 
+    @Override
+    public Object Rf_coerceVector(Object x, int mode) {
+        return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.Rf_coerceVector).call(x, mode);
+    }
+
     @Override
     public Object Rf_mkCharLenCE(Object bytes, int len, int encoding) {
         // TODO: handle encoding properly
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java
index dd28c59af3..a998220115 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java
@@ -104,6 +104,7 @@ public enum RFFIUpCallMethod {
     Rf_asLogical("(object) : sint32"),
     Rf_asReal("(object) : double"),
     Rf_classgets("(object, object) : object"),
+    Rf_coerceVector("(object, sint32) : object"),
     Rf_cons("(object, object) : object"),
     Rf_copyListMatrix("(object, object, sint32) : void"),
     Rf_copyMatrix("(object, object, sint32) : void"),
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TracingUpCallsRFFIImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TracingUpCallsRFFIImpl.java
index 31a6a88c7c..fd78becb64 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TracingUpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TracingUpCallsRFFIImpl.java
@@ -87,6 +87,12 @@ final class TracingUpCallsRFFIImpl implements UpCallsRFFI {
         return delegate.Rf_asChar(x);
     }
 
+    @Override
+    public Object Rf_coerceVector(Object x, int mode) {
+        RFFIUtils.traceUpCall("Rf_coerceVector", x, mode);
+        return delegate.Rf_coerceVector(x, mode);
+    }
+
     @Override
     public Object Rf_mkCharLenCE(Object bytes, int len, int encoding) {
         RFFIUtils.traceUpCall("Rf_mkCharLenCE", bytes);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java
index e8b7a62940..3d96124a1c 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java
@@ -63,6 +63,8 @@ public interface StdUpCallsRFFI {
 
     Object Rf_asChar(Object x);
 
+    Object Rf_coerceVector(Object x, int mode);
+
     Object Rf_mkCharLenCE(@RFFICstring Object bytes, int len, int encoding);
 
     Object Rf_cons(Object car, Object cdr);
diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R
index d482babaac..93443593a8 100644
--- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R
+++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R
@@ -153,3 +153,6 @@ rffi.LENGTH <- function(x) {
 	.Call("test_LENGTH", x)
 }
 
+rffi.coerceVector <- function(x, mode) {
+	.Call("test_coerceVector", x, mode)
+}
diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c
index 8ac5196404..cf78dd91c9 100644
--- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c
+++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c
@@ -33,39 +33,40 @@ static const R_CMethodDef CEntries[]  = {
 #define CALLDEF(name, n)  {#name, (DL_FUNC) &name, n}
 
 static const R_CallMethodDef CallEntries[] = {
-	    CALLDEF(addInt, 2),
-	    CALLDEF(addDouble, 2),
-	    CALLDEF(populateIntVector, 1),
-	    CALLDEF(populateLogicalVector, 1),
-	    CALLDEF(createExternalPtr, 3),
-	    CALLDEF(getExternalPtrAddr, 1),
-	    CALLDEF(invoke_TYPEOF, 1),
-	    CALLDEF(invoke_error, 1),
-	    CALLDEF(dot_external_access_args, 1),
-	    CALLDEF(invoke_isString, 1),
-	    CALLDEF(invoke12, 12),
-	    CALLDEF(interactive, 0),
-	    CALLDEF(tryEval, 2),
-	    CALLDEF(rHomeDir, 0),
-	    CALLDEF(nestedCall1, 2),
-	    CALLDEF(nestedCall2, 1),
-	    CALLDEF(r_home, 0),
-	    CALLDEF(mkStringFromChar, 0),
-	    CALLDEF(mkStringFromBytes, 0),
-	    CALLDEF(null, 0),
-	    CALLDEF(iterate_iarray, 1),
-	    CALLDEF(iterate_iptr, 1),
-	    CALLDEF(preserve_object, 0),
-	    CALLDEF(release_object, 1),
-	    CALLDEF(findvar, 2),
-	    CALLDEF(test_asReal, 1),
-	    CALLDEF(test_asChar, 1),
-	    CALLDEF(test_asInteger, 1),
-	    CALLDEF(test_asLogical, 1),
-		CALLDEF(test_CAR, 1),
-		CALLDEF(test_CDR, 1),
-		CALLDEF(test_LENGTH, 1),
-	    {NULL, NULL, 0}
+        CALLDEF(addInt, 2),
+        CALLDEF(addDouble, 2),
+        CALLDEF(populateIntVector, 1),
+        CALLDEF(populateLogicalVector, 1),
+        CALLDEF(createExternalPtr, 3),
+        CALLDEF(getExternalPtrAddr, 1),
+        CALLDEF(invoke_TYPEOF, 1),
+        CALLDEF(invoke_error, 1),
+        CALLDEF(dot_external_access_args, 1),
+        CALLDEF(invoke_isString, 1),
+        CALLDEF(invoke12, 12),
+        CALLDEF(interactive, 0),
+        CALLDEF(tryEval, 2),
+        CALLDEF(rHomeDir, 0),
+        CALLDEF(nestedCall1, 2),
+        CALLDEF(nestedCall2, 1),
+        CALLDEF(r_home, 0),
+        CALLDEF(mkStringFromChar, 0),
+        CALLDEF(mkStringFromBytes, 0),
+        CALLDEF(null, 0),
+        CALLDEF(iterate_iarray, 1),
+        CALLDEF(iterate_iptr, 1),
+        CALLDEF(preserve_object, 0),
+        CALLDEF(release_object, 1),
+        CALLDEF(findvar, 2),
+        CALLDEF(test_asReal, 1),
+        CALLDEF(test_asChar, 1),
+        CALLDEF(test_asInteger, 1),
+        CALLDEF(test_asLogical, 1),
+        CALLDEF(test_CAR, 1),
+        CALLDEF(test_CDR, 1),
+        CALLDEF(test_LENGTH, 1),
+        CALLDEF(test_coerceVector, 2),
+        {NULL, NULL, 0}
 };
 
 void
diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c
index e15a466e94..364653bd0d 100644
--- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c
+++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c
@@ -317,3 +317,9 @@ SEXP test_CDR(SEXP x) {
 SEXP test_LENGTH(SEXP x) {
 	return ScalarInteger(LENGTH(x));
 }
+
+SEXP test_coerceVector(SEXP x, SEXP mode) {
+    int intMode = INTEGER_VALUE(mode);
+    return Rf_coerceVector(x, intMode);
+}
+
diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h
index 040107cedf..1787b05645 100644
--- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h
+++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h
@@ -86,3 +86,5 @@ extern SEXP test_CDR(SEXP x);
 
 extern SEXP test_LENGTH(SEXP x);
 
+extern SEXP test_coerceVector(SEXP x, SEXP mode);
+
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 8a90c74f38..366264daa3 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
@@ -139467,6 +139467,795 @@ Error in .Call("null", PACKAGE = "foo") :
 #{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); a <- c(1L,2L,3L); x <- rffi.iterate_iarray(a); detach("package:testrffi", unload=T); x }
 [1] 1 2 3
 
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(1L, 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(1L, 0) :
+  cannot coerce type 'integer' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(1L, 1); detach('package:testrffi', unload=T); x }
+`1`
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(1L, 10); detach('package:testrffi', unload=T); x }
+[1] TRUE
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(1L, 13); detach('package:testrffi', unload=T); x }
+[1] 1
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(1L, 14); detach('package:testrffi', unload=T); x }
+[1] 1
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(1L, 15); detach('package:testrffi', unload=T); x }
+[1] 1+0i
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(1L, 16); detach('package:testrffi', unload=T); x }
+[1] "1"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(1L, 19); detach('package:testrffi', unload=T); x }
+[[1]]
+[1] 1
+
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(1L, 24); detach('package:testrffi', unload=T); x }
+[1] 01
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2, 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(2, 0) :
+  cannot coerce type 'double' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2, 1); detach('package:testrffi', unload=T); x }
+`2`
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2, 10); detach('package:testrffi', unload=T); x }
+[1] TRUE
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2, 13); detach('package:testrffi', unload=T); x }
+[1] 2
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2, 14); detach('package:testrffi', unload=T); x }
+[1] 2
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2, 15); detach('package:testrffi', unload=T); x }
+[1] 2+0i
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2, 16); detach('package:testrffi', unload=T); x }
+[1] "2"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2, 19); detach('package:testrffi', unload=T); x }
+[[1]]
+[1] 2
+
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2, 24); detach('package:testrffi', unload=T); x }
+[1] 02
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2.2, 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(2.2, 0) :
+  cannot coerce type 'double' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2.2, 1); detach('package:testrffi', unload=T); x }
+`2.2`
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2.2, 10); detach('package:testrffi', unload=T); x }
+[1] TRUE
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2.2, 13); detach('package:testrffi', unload=T); x }
+[1] 2
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2.2, 14); detach('package:testrffi', unload=T); x }
+[1] 2.2
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2.2, 15); detach('package:testrffi', unload=T); x }
+[1] 2.2+0i
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2.2, 16); detach('package:testrffi', unload=T); x }
+[1] "2.2"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2.2, 19); detach('package:testrffi', unload=T); x }
+[[1]]
+[1] 2.2
+
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2.2, 24); detach('package:testrffi', unload=T); x }
+[1] 02
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(T, 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(T, 0) :
+  cannot coerce type 'logical' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(T, 1); detach('package:testrffi', unload=T); x }
+`TRUE`
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(T, 10); detach('package:testrffi', unload=T); x }
+[1] TRUE
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(T, 13); detach('package:testrffi', unload=T); x }
+[1] 1
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(T, 14); detach('package:testrffi', unload=T); x }
+[1] 1
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(T, 15); detach('package:testrffi', unload=T); x }
+[1] 1+0i
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(T, 16); detach('package:testrffi', unload=T); x }
+[1] "TRUE"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(T, 19); detach('package:testrffi', unload=T); x }
+[[1]]
+[1] TRUE
+
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(T, 24); detach('package:testrffi', unload=T); x }
+[1] 01
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(2.3, 3.4), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(c(2.3, 3.4), 0) :
+  cannot coerce type 'double' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(2.3, 3.4), 1); detach('package:testrffi', unload=T); x }
+`2.3`
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(2.3, 3.4), 10); detach('package:testrffi', unload=T); x }
+[1] TRUE TRUE
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(2.3, 3.4), 13); detach('package:testrffi', unload=T); x }
+[1] 2 3
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(2.3, 3.4), 14); detach('package:testrffi', unload=T); x }
+[1] 2.3 3.4
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(2.3, 3.4), 15); detach('package:testrffi', unload=T); x }
+[1] 2.3+0i 3.4+0i
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(2.3, 3.4), 16); detach('package:testrffi', unload=T); x }
+[1] "2.3" "3.4"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(2.3, 3.4), 19); detach('package:testrffi', unload=T); x }
+[[1]]
+[1] 2.3
+
+[[2]]
+[1] 3.4
+
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(2.3, 3.4), 24); detach('package:testrffi', unload=T); x }
+[1] 02 03
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(5,6), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(c(5, 6), 0) :
+  cannot coerce type 'double' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(5,6), 1); detach('package:testrffi', unload=T); x }
+`5`
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(5,6), 10); detach('package:testrffi', unload=T); x }
+[1] TRUE TRUE
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(5,6), 13); detach('package:testrffi', unload=T); x }
+[1] 5 6
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(5,6), 14); detach('package:testrffi', unload=T); x }
+[1] 5 6
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(5,6), 15); detach('package:testrffi', unload=T); x }
+[1] 5+0i 6+0i
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(5,6), 16); detach('package:testrffi', unload=T); x }
+[1] "5" "6"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(5,6), 19); detach('package:testrffi', unload=T); x }
+[[1]]
+[1] 5
+
+[[2]]
+[1] 6
+
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(5,6), 24); detach('package:testrffi', unload=T); x }
+[1] 05 06
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(T, F), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(c(T, F), 0) :
+  cannot coerce type 'logical' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(T, F), 1); detach('package:testrffi', unload=T); x }
+`TRUE`
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(T, F), 10); detach('package:testrffi', unload=T); x }
+[1]  TRUE FALSE
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(T, F), 13); detach('package:testrffi', unload=T); x }
+[1] 1 0
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(T, F), 14); detach('package:testrffi', unload=T); x }
+[1] 1 0
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(T, F), 15); detach('package:testrffi', unload=T); x }
+[1] 1+0i 0+0i
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(T, F), 16); detach('package:testrffi', unload=T); x }
+[1] "TRUE"  "FALSE"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(T, F), 19); detach('package:testrffi', unload=T); x }
+[[1]]
+[1] TRUE
+
+[[2]]
+[1] FALSE
+
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(T, F), 24); detach('package:testrffi', unload=T); x }
+[1] 01 00
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(character(), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(character(), 0) :
+  cannot coerce type 'character' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(character(), 1); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(character(), 1) :
+  invalid data of mode 'character' (too short)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(character(), 10); detach('package:testrffi', unload=T); x }
+logical(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(character(), 13); detach('package:testrffi', unload=T); x }
+integer(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(character(), 14); detach('package:testrffi', unload=T); x }
+numeric(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(character(), 15); detach('package:testrffi', unload=T); x }
+complex(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(character(), 16); detach('package:testrffi', unload=T); x }
+character(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(character(), 19); detach('package:testrffi', unload=T); x }
+list()
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(character(), 24); detach('package:testrffi', unload=T); x }
+raw(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(integer(), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(integer(), 0) :
+  cannot coerce type 'integer' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(integer(), 1); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(integer(), 1) :
+  invalid data of mode 'integer' (too short)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(integer(), 10); detach('package:testrffi', unload=T); x }
+logical(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(integer(), 13); detach('package:testrffi', unload=T); x }
+integer(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(integer(), 14); detach('package:testrffi', unload=T); x }
+numeric(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(integer(), 15); detach('package:testrffi', unload=T); x }
+complex(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(integer(), 16); detach('package:testrffi', unload=T); x }
+character(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(integer(), 19); detach('package:testrffi', unload=T); x }
+list()
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(integer(), 24); detach('package:testrffi', unload=T); x }
+raw(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(list(), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(list(), 0) :
+  unimplemented type 'list' in 'coerceVectorList'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(list(), 1); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(list(), 1) :
+  invalid type/length (symbol/0) in vector allocation
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(list(), 10); detach('package:testrffi', unload=T); x }
+logical(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(list(), 13); detach('package:testrffi', unload=T); x }
+integer(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(list(), 14); detach('package:testrffi', unload=T); x }
+numeric(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(list(), 15); detach('package:testrffi', unload=T); x }
+complex(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(list(), 16); detach('package:testrffi', unload=T); x }
+character(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(list(), 19); detach('package:testrffi', unload=T); x }
+list()
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(list(), 24); detach('package:testrffi', unload=T); x }
+raw(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(logical(), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(logical(), 0) :
+  cannot coerce type 'logical' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(logical(), 1); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(logical(), 1) :
+  invalid data of mode 'logical' (too short)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(logical(), 10); detach('package:testrffi', unload=T); x }
+logical(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(logical(), 13); detach('package:testrffi', unload=T); x }
+integer(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(logical(), 14); detach('package:testrffi', unload=T); x }
+numeric(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(logical(), 15); detach('package:testrffi', unload=T); x }
+complex(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(logical(), 16); detach('package:testrffi', unload=T); x }
+character(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(logical(), 19); detach('package:testrffi', unload=T); x }
+list()
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(logical(), 24); detach('package:testrffi', unload=T); x }
+raw(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(numeric(), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(numeric(), 0) :
+  cannot coerce type 'double' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(numeric(), 1); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(numeric(), 1) :
+  invalid data of mode 'double' (too short)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(numeric(), 10); detach('package:testrffi', unload=T); x }
+logical(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(numeric(), 13); detach('package:testrffi', unload=T); x }
+integer(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(numeric(), 14); detach('package:testrffi', unload=T); x }
+numeric(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(numeric(), 15); detach('package:testrffi', unload=T); x }
+complex(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(numeric(), 16); detach('package:testrffi', unload=T); x }
+character(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(numeric(), 19); detach('package:testrffi', unload=T); x }
+list()
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(numeric(), 24); detach('package:testrffi', unload=T); x }
+raw(0)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(1L,names='a',dim=c(1,1),myattr='q'), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(structure(1L, names = "a", dim = c(1, 1), myattr = "q"),  :
+  cannot coerce type 'integer' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(1L,names='a',dim=c(1,1),myattr='q'), 1); detach('package:testrffi', unload=T); x }
+`1`
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(1L,names='a',dim=c(1,1),myattr='q'), 10); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,] TRUE
+attr(,"names")
+[1] "a"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(1L,names='a',dim=c(1,1),myattr='q'), 13); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,]    1
+attr(,"names")
+[1] "a"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(1L,names='a',dim=c(1,1),myattr='q'), 14); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,]    1
+attr(,"names")
+[1] "a"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(1L,names='a',dim=c(1,1),myattr='q'), 15); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,] 1+0i
+attr(,"names")
+[1] "a"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(1L,names='a',dim=c(1,1),myattr='q'), 16); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,] "1"
+attr(,"names")
+[1] "a"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(1L,names='a',dim=c(1,1),myattr='q'), 19); detach('package:testrffi', unload=T); x }
+$a
+[1] 1
+
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(1L,names='a',dim=c(1,1),myattr='q'), 24); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,]   01
+attr(,"names")
+[1] "a"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(2.2, names='b',dim=c(1,1),myattr='q'), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(structure(2.2, names = "b", dim = c(1, 1),  :
+  cannot coerce type 'double' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(2.2, names='b',dim=c(1,1),myattr='q'), 1); detach('package:testrffi', unload=T); x }
+`2.2`
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(2.2, names='b',dim=c(1,1),myattr='q'), 10); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,] TRUE
+attr(,"names")
+[1] "b"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(2.2, names='b',dim=c(1,1),myattr='q'), 13); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,]    2
+attr(,"names")
+[1] "b"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(2.2, names='b',dim=c(1,1),myattr='q'), 14); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,]  2.2
+attr(,"names")
+[1] "b"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(2.2, names='b',dim=c(1,1),myattr='q'), 15); detach('package:testrffi', unload=T); x }
+       [,1]
+[1,] 2.2+0i
+attr(,"names")
+[1] "b"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(2.2, names='b',dim=c(1,1),myattr='q'), 16); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,] "2.2"
+attr(,"names")
+[1] "b"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(2.2, names='b',dim=c(1,1),myattr='q'), 19); detach('package:testrffi', unload=T); x }
+$b
+[1] 2.2
+
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(2.2, names='b',dim=c(1,1),myattr='q'), 24); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,]   02
+attr(,"names")
+[1] "b"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(T, names='c',dim=c(1,1),myattr='q'), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(structure(T, names = "c", dim = c(1, 1), myattr = "q"),  :
+  cannot coerce type 'logical' to vector of type 'NULL'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(T, names='c',dim=c(1,1),myattr='q'), 1); detach('package:testrffi', unload=T); x }
+`TRUE`
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(T, names='c',dim=c(1,1),myattr='q'), 10); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,] TRUE
+attr(,"names")
+[1] "c"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(T, names='c',dim=c(1,1),myattr='q'), 13); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,]    1
+attr(,"names")
+[1] "c"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(T, names='c',dim=c(1,1),myattr='q'), 14); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,]    1
+attr(,"names")
+[1] "c"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(T, names='c',dim=c(1,1),myattr='q'), 15); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,] 1+0i
+attr(,"names")
+[1] "c"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(T, names='c',dim=c(1,1),myattr='q'), 16); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,] "TRUE"
+attr(,"names")
+[1] "c"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(T, names='c',dim=c(1,1),myattr='q'), 19); detach('package:testrffi', unload=T); x }
+$c
+[1] TRUE
+
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(T, names='c',dim=c(1,1),myattr='q'), 24); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,]   01
+attr(,"names")
+[1] "c"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(list(1,'42'), names=c('q','w'),dim=c(2,1),myattr='q'), 0); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(structure(list(1, "42"), names = c("q", "w"),  :
+  unimplemented type 'list' in 'coerceVectorList'
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(list(1,'42'), names=c('q','w'),dim=c(2,1),myattr='q'), 1); detach('package:testrffi', unload=T); x }
+Error in rffi.coerceVector(structure(list(1, "42"), names = c("q", "w"),  :
+  invalid type/length (symbol/2) in vector allocation
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(list(1,'42'), names=c('q','w'),dim=c(2,1),myattr='q'), 10); detach('package:testrffi', unload=T); x }
+   q    w
+TRUE   NA
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(list(1,'42'), names=c('q','w'),dim=c(2,1),myattr='q'), 13); detach('package:testrffi', unload=T); x }
+ q  w
+ 1 42
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(list(1,'42'), names=c('q','w'),dim=c(2,1),myattr='q'), 14); detach('package:testrffi', unload=T); x }
+ q  w
+ 1 42
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(list(1,'42'), names=c('q','w'),dim=c(2,1),myattr='q'), 15); detach('package:testrffi', unload=T); x }
+    q     w
+ 1+0i 42+0i
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(list(1,'42'), names=c('q','w'),dim=c(2,1),myattr='q'), 16); detach('package:testrffi', unload=T); x }
+   q    w
+ "1" "42"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(list(1,'42'), names=c('q','w'),dim=c(2,1),myattr='q'), 19); detach('package:testrffi', unload=T); x }
+     [,1]
+[1,] 1
+[2,] "42"
+attr(,"names")
+[1] "q" "w"
+attr(,"myattr")
+[1] "q"
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVector#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(list(1,'42'), names=c('q','w'),dim=c(2,1),myattr='q'), 24); detach('package:testrffi', unload=T); x }
+ q  w
+01 2a
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2, 20); detach('package:testrffi', unload=T); x }
+expression(2)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(2.2, 20); detach('package:testrffi', unload=T); x }
+expression(2.2)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(T, 20); detach('package:testrffi', unload=T); x }
+expression(TRUE)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(2.3, 3.4), 20); detach('package:testrffi', unload=T); x }
+expression(2.3, 3.4)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(5,6), 20); detach('package:testrffi', unload=T); x }
+expression(5, 6)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(c(T, F), 20); detach('package:testrffi', unload=T); x }
+expression(TRUE, FALSE)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(character(), 20); detach('package:testrffi', unload=T); x }
+expression()
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(integer(), 20); detach('package:testrffi', unload=T); x }
+expression()
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(list(), 20); detach('package:testrffi', unload=T); x }
+expression()
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(logical(), 20); detach('package:testrffi', unload=T); x }
+expression()
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(numeric(), 20); detach('package:testrffi', unload=T); x }
+expression()
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(2.2, names='b',dim=c(1,1),myattr='q'), 20); detach('package:testrffi', unload=T); x }
+expression(2.2)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Output.IgnoreErrorMessage#Output.MayIgnoreWarningContext#Output.MayIgnoreErrorContext#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(T, names='c',dim=c(1,1),myattr='q'), 20); detach('package:testrffi', unload=T); x }
+expression(TRUE)
+
+##com.oracle.truffle.r.test.rffi.TestRFFIPackageCoercions.testCoerceVectorToExpression#Ignored.Unimplemented#
+#{ library('testrffi', lib.loc = 'tmptest/com.oracle.truffle.r.test.rpackages'); x <- rffi.coerceVector(structure(list(1,'x'), names=c('q','w'),dim=c(2,1),myattr='q'), 20); detach('package:testrffi', unload=T); x }
+expression(q = 1, w = "x")
+attr(,"names")
+[1] "q" "w"
+attr(,"myattr")
+[1] "q"
+
 ##com.oracle.truffle.r.test.rffi.TestUserRNG.testUserRNG#
 #{ dyn.load("com.oracle.truffle.r.test.native/urand/lib/liburand.so"); RNGkind("user"); print(RNGkind()); set.seed(4567); runif(10) }
 [1] "user-supplied" "Inversion"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackageCoercions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackageCoercions.java
new file mode 100644
index 0000000000..9bff0cf831
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackageCoercions.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014, 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.rffi;
+
+import static com.oracle.truffle.r.runtime.gnur.SEXPTYPE.CPLXSXP;
+import static com.oracle.truffle.r.runtime.gnur.SEXPTYPE.EXPRSXP;
+import static com.oracle.truffle.r.runtime.gnur.SEXPTYPE.INTSXP;
+import static com.oracle.truffle.r.runtime.gnur.SEXPTYPE.LGLSXP;
+import static com.oracle.truffle.r.runtime.gnur.SEXPTYPE.NILSXP;
+import static com.oracle.truffle.r.runtime.gnur.SEXPTYPE.RAWSXP;
+import static com.oracle.truffle.r.runtime.gnur.SEXPTYPE.REALSXP;
+import static com.oracle.truffle.r.runtime.gnur.SEXPTYPE.STRSXP;
+import static com.oracle.truffle.r.runtime.gnur.SEXPTYPE.SYMSXP;
+import static com.oracle.truffle.r.runtime.gnur.SEXPTYPE.VECSXP;
+
+import java.util.Arrays;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
+import com.oracle.truffle.r.test.rpackages.TestRPackages;
+
+public class TestRFFIPackageCoercions extends TestRPackages {
+
+    private static final String[] TEST_PACKAGES = new String[]{"testrffi"};
+
+    @BeforeClass
+    public static void setupInstallMyTestPackages() {
+        setupInstallTestPackages(TEST_PACKAGES);
+    }
+
+    @AfterClass
+    public static void tearDownUninstallMyTestPackages() {
+        tearDownUninstallTestPackages();
+    }
+
+    private String addLib(String test) {
+        return "{ library('testrffi', lib.loc = '" + TestRPackages.libLoc() + "'); x <- " + test + "; detach('package:testrffi', unload=T); x }";
+    }
+
+    private static final String[] COERCION_VALUES_FOR_EXPR = new String[]{
+                    "2", "2.2", "T", "integer()", "numeric()", "logical()", "character()", "c(5,6)", "c(2.3, 3.4)", "c(T, F)",
+                    "list()", "structure(2.2, names='b',dim=c(1,1),myattr='q')", "structure(T, names='c',dim=c(1,1),myattr='q')"};
+
+    private static final String[] COERCION_VALUES = new String[]{
+                    "1L", "2", "2.2", "T", "integer()", "numeric()", "logical()", "character()", "c(5,6)", "c(2.3, 3.4)",
+                    "c(T, F)", "list()", "structure(1L,names='a',dim=c(1,1),myattr='q')", "structure(2.2, names='b',dim=c(1,1),myattr='q')",
+                    "structure(T, names='c',dim=c(1,1),myattr='q')", "structure(list(1,'42'), names=c('q','w'),dim=c(2,1),myattr='q')"};
+
+    private static final SEXPTYPE[] COERCION_TYPES = new SEXPTYPE[]{SYMSXP, NILSXP, VECSXP, INTSXP, REALSXP, LGLSXP, STRSXP, CPLXSXP, RAWSXP};
+
+    private static final String[] COERCION_MODES = Arrays.stream(COERCION_TYPES).map(x -> Integer.toString(x.code)).toArray(n -> new String[n]);
+
+    @Test
+    public void testCoerceVector() {
+        String[] tests = template(addLib("rffi.coerceVector(%0, %1)"), COERCION_VALUES, COERCION_MODES);
+        assertEval(Output.MayIgnoreWarningContext, Output.MayIgnoreErrorContext, tests);
+    }
+
+    @Test
+    public void testCoerceVectorToExpression() {
+        // Note: inconsistency when printing expression(1L) FastR prints just "expression(1)"
+        String[] tests = template(addLib("rffi.coerceVector(%0, %1)"), COERCION_VALUES_FOR_EXPR, new String[]{Integer.toString(EXPRSXP.code)});
+        assertEval(Output.IgnoreErrorMessage, Output.MayIgnoreWarningContext, Output.MayIgnoreErrorContext, tests);
+        // removes the attributes when its single value, but keeps them when it's a list
+        assertEval(Ignored.Unimplemented, addLib("rffi.coerceVector(structure(list(1,'x'), names=c('q','w'),dim=c(2,1),myattr='q'), " + EXPRSXP.code + ")"));
+    }
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRPackages.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRPackages.java
index fbac0b3aa6..40e4f8d269 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRPackages.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRPackages.java
@@ -164,6 +164,8 @@ public abstract class TestRPackages extends TestBase {
         }
     }
 
+    private boolean packagesInstallSuccess = true;
+
     @Override
     public void beforeEval() {
         if (needsInstall) {
@@ -177,11 +179,14 @@ public abstract class TestRPackages extends TestBase {
                 System.out.printf(".pkg: %s.", p);
                 PackagePath packagePath = getPackagePaths(p, resolver.getPath(p));
                 if (!installPackage(packagePath)) {
+                    packagesInstallSuccess = false;
                     Assert.fail(String.format("package %s failed to install", p));
                 }
             }
             System.out.printf(".end install.");
         }
+        // This makes sure that any consequent tests fail with informative error
+        Assert.assertTrue("Error during package installation process.", packagesInstallSuccess);
     }
 
     protected static void tearDownUninstallTestPackages() {
-- 
GitLab