From 118da92603267f86228b58f91a45c97a2593a8fd Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Fri, 19 May 2017 15:01:47 +0200 Subject: [PATCH] Fix: serialization can handle promises that appear in varargs --- .../src/com/oracle/truffle/r/runtime/RSerialize.java | 3 ++- .../oracle/truffle/r/runtime/data/RArgsValuesAndNames.java | 4 +++- .../src/com/oracle/truffle/r/test/ExpectedTestOutput.test | 4 ++++ .../truffle/r/test/builtins/TestBuiltin_serialize.java | 5 +++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java index eda8d1fee8..8415803a34 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java @@ -1474,7 +1474,8 @@ public class RSerialize { attributes = null; } } - boolean hasTag = gnuRType == SEXPTYPE.CLOSXP || (gnuRType == SEXPTYPE.PROMSXP && !((RPromise) obj).isEvaluated()) || (type == SEXPTYPE.LISTSXP && !((RPairList) obj).isNullTag()); + boolean hasTag = gnuRType == SEXPTYPE.CLOSXP || gnuRType == SEXPTYPE.DOTSXP || (gnuRType == SEXPTYPE.PROMSXP && !((RPromise) obj).isEvaluated()) || + (type == SEXPTYPE.LISTSXP && !((RPairList) obj).isNullTag()); int gpbits = getGPBits(obj); int flags = Flags.packFlags(gnuRType, gpbits, isObject(obj), attributes != null, hasTag); stream.writeInt(flags); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java index 86d2782285..1f874d0842 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java @@ -51,7 +51,9 @@ public final class RArgsValuesAndNames extends Arguments<Object> implements RTyp @Override public int getTypedValueInfo() { - throw RInternalError.shouldNotReachHere(); + // RArgsValuesAndNames can get serialized under specific circumstances (ggplot2 does that) + // and getTypedValueInfo() must be defined for this to work. + return 0; } @Override 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 faec0e21a7..0635bc059c 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 @@ -62412,6 +62412,10 @@ Error in seq.int(NaN) : 'from' cannot be NA, NaN or infinite #argv <- list(from = 0, to = 0.793110173512391, length.out = FALSE);do.call('seq.int', argv); integer(0) +##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testSerializeWithPromises# +#{ f <- function(...) serialize(mget('...'),NULL); length(unserialize(f(a=3,b=2,c=1))[[1]]); } +[1] 3 + ##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize#Ignored.ImplementationError# #options(keep.source=FALSE); fc <- setClass('FooSerial1', representation(a = 'call')); serialize(fc, connection=NULL) [1] 58 0a 00 00 00 02 00 03 03 02 00 02 03 00 00 01 07 03 00 00 04 02 00 00 00 diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java index 3e031ad10e..018b22c652 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java @@ -111,4 +111,9 @@ public class TestBuiltin_serialize extends TestBase { assertEval("{ options(keep.source=FALSE); f <- function() NULL; attributes(f) <- list(skeleton=quote(`<undef>`())); data <- serialize(f, conn=NULL); unserialize(conn=data) }"); } + + @Test + public void testSerializeWithPromises() { + assertEval("{ f <- function(...) serialize(mget('...'),NULL); length(unserialize(f(a=3,b=2,c=1))[[1]]); }"); + } } -- GitLab