diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java index d537893caf75a3d2f07d1524621af4597071ea0f..58a20155f7ccb66525a29d68c3ee0e4be69412c8 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java @@ -36,7 +36,6 @@ import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RShareable; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; /** @@ -205,8 +204,8 @@ public class RChannel { RAttributable attributable = (RAttributable) msg; RAttributes attr = attributable.getAttributes(); RAttributes newAttr = createShareableSlow(attr); - if (attributable instanceof RAbstractVector) { - attributable = ((RAbstractVector) msg).copy(); + if (newAttr != attr && attributable instanceof RShareable) { + attributable = (RAttributable) ((RShareable) msg).copy(); } // see convertListAttributesToPrivate() why it is OK to use initAttributes() here attributable.initAttributes(newAttr); @@ -235,8 +234,13 @@ public class RChannel { // by different threads makeShared(o); if (o instanceof RAttributable && ((RAttributable) o).getAttributes() != null) { - return convertObjectAttributesToPrivate(o); + Object newObj = convertObjectAttributesToPrivate(o); + if (newObj == o) { + makeShared(o); + } // otherwise a copy has been created to store new attributes + return newObj; } else { + makeShared(o); return o; } } else { 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 e185832122485adabd8797a831ef1d48c34afe26..27248ed5f742b9c2a7e4384fadd6096d4ce84625 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 @@ -108256,6 +108256,74 @@ a b c d a b c d e 1 2 3 4 5 +##com.oracle.truffle.r.test.library.fastr.TestChannels.dummyTest +#42 +[1] 42 + +##com.oracle.truffle.r.test.library.fastr.TestChannels.runRSourceTests +#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels1.R") } +[1] 7 42 + +##com.oracle.truffle.r.test.library.fastr.TestChannels.runRSourceTests +#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels10.R") } +[1] 7 42 + +##com.oracle.truffle.r.test.library.fastr.TestChannels.runRSourceTests +#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels11.R") } +[1] 7 42 + +##com.oracle.truffle.r.test.library.fastr.TestChannels.runRSourceTests +#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels2.R") } +[[1]] +[1] 7 + +[[2]] +[1] 42 + + +##com.oracle.truffle.r.test.library.fastr.TestChannels.runRSourceTests +#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels3.R") } +[1] 49 + +##com.oracle.truffle.r.test.library.fastr.TestChannels.runRSourceTests +#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels4.R") } +[[1]] +[1] 7 + +[[2]] +[1] FALSE + + +##com.oracle.truffle.r.test.library.fastr.TestChannels.runRSourceTests +#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels5.R") } +[[1]] +[1] 7 + +[[2]] +[1] FALSE + + +##com.oracle.truffle.r.test.library.fastr.TestChannels.runRSourceTests +#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels6.R") } +[[1]] +[1] 7 + +[[2]] +[1] FALSE + + +##com.oracle.truffle.r.test.library.fastr.TestChannels.runRSourceTests +#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels7.R") } +[1] TRUE + +##com.oracle.truffle.r.test.library.fastr.TestChannels.runRSourceTests +#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels8.R") } +[1] TRUE + +##com.oracle.truffle.r.test.library.fastr.TestChannels.runRSourceTests +#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels9.R") } +[1] TRUE FALSE + ##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropEval #if (length(grep("FastR", R.Version()$version.string)) != 1) { 1 } else { .fastr.interop.eval('application/x-r', '1') } [1] 1 diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels10.R b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels10.R new file mode 100644 index 0000000000000000000000000000000000000000..27a0504a89621d2cbb489e849b0720b8f3e7f263 --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels10.R @@ -0,0 +1,16 @@ +# test remote updated of atomic vector with shareable attribute (must stay private) + +if (length(grep("FastR", R.Version()$version.string)) == 1) { + ch <- .fastr.channel.create(1L) + code <- "ch <- .fastr.channel.get(1L); x<-.fastr.channel.receive(ch); x[1]<-7; .fastr.channel.send(ch, x)" + cx <- .fastr.context.spawn(code) + y<-c(42) + attr(y, "foo") <- c("foo", "bar") + .fastr.channel.send(ch, y) + x<-.fastr.channel.receive(ch) + .fastr.context.join(cx) + .fastr.channel.close(ch) + print(c(x,y)) +} else { + print(c(7L, 42L)) +} diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels11.R b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels11.R new file mode 100644 index 0000000000000000000000000000000000000000..8a29a1e7f5579e8aa80ff3b55e2cde4377ea2d65 --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels11.R @@ -0,0 +1,16 @@ +# test remote updated of atomic vector with serializable attribute (must stay private) + +if (length(grep("FastR", R.Version()$version.string)) == 1) { + ch <- .fastr.channel.create(1L) + code <- "ch <- .fastr.channel.get(1L); x<-.fastr.channel.receive(ch); x[1]<-7; .fastr.channel.send(ch, x)" + cx <- .fastr.context.spawn(code) + y<-c(42) + attr(y, "foo") <- function() 42 + .fastr.channel.send(ch, y) + x<-.fastr.channel.receive(ch) + .fastr.context.join(cx) + .fastr.channel.close(ch) + print(c(x,y)) +} else { + print(c(7L, 42L)) +} diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels2.R b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels2.R index 1879ea428d7f3aa5464ba037403ac00025d1a2ce..3e4b27396ea2c358d0354d85dba0e9b678ac93fe 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels2.R +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/channels/R/channels2.R @@ -6,7 +6,7 @@ if (length(grep("FastR", R.Version()$version.string)) == 1) { cx <- .fastr.context.spawn(code) y<-list(c(42)) .fastr.channel.send(ch, y) - x<-fastr.channel.receive(ch) + x<-.fastr.channel.receive(ch) .fastr.context.join(cx) .fastr.channel.close(ch) print(c(x,y)) diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestChannels.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestChannels.java index 31fb033fde9bcc41309ab36cd91dab4bf010042b..86c316ebabbdc06ae6a7d8456d2591e417e03861 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestChannels.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestChannels.java @@ -22,6 +22,8 @@ */ package com.oracle.truffle.r.test.library.fastr; +import org.junit.Test; + import com.oracle.truffle.r.test.TestRBase; public class TestChannels extends TestRBase { @@ -30,4 +32,12 @@ public class TestChannels extends TestRBase { public String getTestDir() { return "channels"; } + + /** + * Needs to include a dummy test, otherwise JUnit does not pick it up for execution. + */ + @Test + public void dummyTest() { + assertEval("42"); + } }