diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java index 61c1891486cc1a2a936fc768a41d925757055404..cea19e14d2bdd51e5a2799cfceb1d3c6643494bf 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java @@ -32,6 +32,7 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.object.DynamicObject; @@ -100,7 +101,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { @Child private DeleteElementsNode deleteElementsNode; @Child private SetNamesAttributeNode setNamesNode; - CachedReplaceVectorNode(ElementAccessMode mode, RTypedValue vector, Object[] positions, RTypedValue value, boolean updatePositionNames, boolean recursive) { + CachedReplaceVectorNode(ElementAccessMode mode, RTypedValue vector, Object[] positions, Class<?> valueClass, RType valueType, boolean updatePositionNames, boolean recursive) { super(mode, vector, positions, recursive); if (numberOfDimensions == 1 && positions[0] instanceof String || positions[0] instanceof RAbstractStringVector) { @@ -110,8 +111,8 @@ final class CachedReplaceVectorNode extends CachedVectorNode { } this.vectorClass = vector.getClass(); - this.valueClass = value.getClass(); - this.valueType = value.getRType(); + this.valueClass = valueClass; + this.valueType = valueType; this.castType = resolveCastVectorType(); verifyCastType(this.castType); this.castVectorNode = createCastVectorNode(); @@ -142,7 +143,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { Object castVector = vectorClass.cast(originalVector); Object castValue = valueClass.cast(originalValues); - RTypedValue value; + Object value; if (valueType == RType.Null) { if (vectorType == RType.Null) { // we cast Null to Logical, but in the end it will fold and return Null @@ -153,7 +154,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { value = castType.getEmpty(); } } else { - value = (RTypedValue) castValue; + value = castValue; } int appliedValueLength; @@ -562,7 +563,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { } if (copyPositionNames == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - copyPositionNames = insert(new CachedReplaceVectorNode(mode, names, positions, positionNames, false, recursive)); + copyPositionNames = insert(new CachedReplaceVectorNode(mode, names, positions, positionNames.getClass(), positionNames.getRType(), false, recursive)); } assert copyPositionNames.isSupported(names, positions, positionNames); RAbstractStringVector newNames = (RAbstractStringVector) copyPositionNames.apply(names, positions, positionNames); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java index 81a7c3d14718c8de4bb34db1dc5e543b850092f7..be2aeca6132a03a751aabf4b37785dd88bd0ee73 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java @@ -42,6 +42,7 @@ import com.oracle.truffle.r.nodes.unary.FirstStringNode; import com.oracle.truffle.r.runtime.interop.R2Foreign; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -92,10 +93,6 @@ public abstract class ReplaceVectorNode extends RBaseNode { return Message.WRITE.createNode(); } - protected static boolean isForeignObject(TruffleObject object) { - return RRuntime.isForeignObject(object); - } - protected FirstStringNode createFirstString() { return FirstStringNode.createWithError(RError.Message.GENERIC, "Cannot corce position to character for foreign access."); } @@ -184,7 +181,8 @@ public abstract class ReplaceVectorNode extends RBaseNode { } protected static CachedReplaceVectorNode createDefaultCached(ReplaceVectorNode node, Object vector, Object[] positions, Object value) { - return new CachedReplaceVectorNode(node.mode, (RTypedValue) vector, positions, (RTypedValue) value, true, node.recursive); + return new CachedReplaceVectorNode(node.mode, (RTypedValue) vector, positions, value.getClass(), RRuntime.isForeignObject(value) ? RType.TruffleObject : ((RTypedValue) value).getRType(), true, + node.recursive); } public ElementAccessMode getMode() { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java index 8f9270d9ccd8e45a5b8f76099ba5f391ac604cd8..ab744903fc74bb2b3cadb87d7d754738ed94428c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java @@ -44,7 +44,6 @@ import com.oracle.truffle.r.runtime.data.RIntSequence; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RScalarVector; -import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; @@ -85,12 +84,12 @@ abstract class WriteIndexedVectorNode extends Node { private final NACheck positionNACheck = NACheck.create(); private final ConditionProfile resetIndexProfile = ConditionProfile.createBinaryProfile(); - @Child private WriteIndexedScalarNode<RAbstractVector, RTypedValue> scalarNode; + @Child private WriteIndexedScalarNode<RAbstractVector, Object> scalarNode; @Child private WriteIndexedVectorNode innerVectorNode; @SuppressWarnings("unchecked") protected WriteIndexedVectorNode(RType vectorType, int totalDimensions, int dimensionIndex, boolean positionAppliesToRight, boolean skipNA, boolean setListElementAsObject, boolean isReplace) { - this.scalarNode = (WriteIndexedScalarNode<RAbstractVector, RTypedValue>) createIndexedAction(vectorType, setListElementAsObject, isReplace); + this.scalarNode = (WriteIndexedScalarNode<RAbstractVector, Object>) createIndexedAction(vectorType, setListElementAsObject, isReplace); this.dimensionIndex = dimensionIndex; this.totalDimensions = totalDimensions; this.positionsApplyToRight = positionAppliesToRight; @@ -125,7 +124,7 @@ abstract class WriteIndexedVectorNode extends Node { } public final void apply(RAbstractVector left, int leftLength, - Object[] positions, RTypedValue right, int rightLength, int[] positionTargetDimensions) { + Object[] positions, Object right, int rightLength, int[] positionTargetDimensions) { assert left.getLength() == leftLength; assert totalDimensions == positions.length : "totalDimensions must be constant per vector write node"; @@ -162,7 +161,7 @@ abstract class WriteIndexedVectorNode extends Node { private int applyImpl(// RAbstractVector left, Object leftStore, int leftBase, int leftLength, Object targetDimensions, int targetDimension, Object[] positions, int positionOffset, - RTypedValue right, Object rightStore, int rightBase, int rightLength, boolean parentNA) { + Object right, Object rightStore, int rightBase, int rightLength, boolean parentNA) { Object position = positionClassProfile.profile(positions[dimensionIndex]); @@ -188,7 +187,7 @@ abstract class WriteIndexedVectorNode extends Node { protected abstract int execute(RAbstractVector left, Object leftStore, int storeBase, int storeLength, Object targetDimensions, int targetDimension, Object[] positions, Object position, int positionOffset, int positionLength, - RTypedValue right, Object rightStore, int valueBase, int valueLength, boolean parentNA); + Object right, Object rightStore, int valueBase, int valueLength, boolean parentNA); @Specialization protected int doMissing(RAbstractVector left, Object leftStore, int leftBase, int leftLength, Object targetDimensions, int targetDimension, @@ -209,7 +208,7 @@ abstract class WriteIndexedVectorNode extends Node { @Specialization protected int doLogicalPosition(RAbstractVector left, Object leftStore, int leftBase, int leftLength, Object targetDimensions, int targetDimension, Object[] positions, RAbstractLogicalVector position, int positionOffset, int positionLength, - RTypedValue right, Object rightStore, int rightBase, int rightLength, boolean parentNA, + Object right, Object rightStore, int rightBase, int rightLength, boolean parentNA, @Cached("create()") BranchProfile wasTrue, @Cached("create()") AlwaysOnBranchProfile outOfBounds, @Cached("createCountingProfile()") LoopConditionProfile profile, @@ -254,7 +253,7 @@ abstract class WriteIndexedVectorNode extends Node { @Specialization(rewriteOn = SlowPathException.class) protected int doIntegerSequencePosition(RAbstractVector left, Object leftStore, int leftBase, int leftLength, Object targetDimensions, @SuppressWarnings("unused") int targetDimension, Object[] positions, RIntSequence position, int positionOffset, int positionLength, - RTypedValue right, Object rightStore, int rightBase, int rightLength, boolean parentNA, + Object right, Object rightStore, int rightBase, int rightLength, boolean parentNA, @Cached("create()") IntValueProfile startProfile, @Cached("create()") IntValueProfile strideProfile, @Cached("createBinaryProfile()") ConditionProfile conditionProfile, @@ -293,7 +292,7 @@ abstract class WriteIndexedVectorNode extends Node { @Specialization(replaces = "doIntegerSequencePosition") protected int doIntegerPosition(RAbstractVector left, Object leftStore, int leftBase, int leftLength, Object targetDimensions, @SuppressWarnings("unused") int targetDimension, Object[] positions, RAbstractIntVector position, int positionOffset, int positionLength, - RTypedValue right, Object rightStore, int rightBase, int rightLength, boolean parentNA, + Object right, Object rightStore, int rightBase, int rightLength, boolean parentNA, @Cached("createCountingProfile()") LoopConditionProfile lengthProfile) { positionNACheck.enable(position); int rightIndex = rightBase; @@ -318,7 +317,7 @@ abstract class WriteIndexedVectorNode extends Node { private int applyInner(// RAbstractVector left, Object leftStore, int leftBase, int leftLength, Object targetDimensions, Object[] positions, int positionOffset, int positionValue, - RTypedValue right, Object rightStore, int rightLength, int actionIndex, boolean isNA) { + Object right, Object rightStore, int rightLength, int actionIndex, boolean isNA) { int newTargetIndex = leftBase + positionValue * positionOffset; if (dimensionIndex == 0) { // for-loops leaf for innermost dimension @@ -354,7 +353,7 @@ abstract class WriteIndexedVectorNode extends Node { } } - private static WriteIndexedScalarNode<? extends RAbstractVector, ? extends RTypedValue> createIndexedAction(RType type, boolean setListElementAsObject, boolean isReplace) { + private static WriteIndexedScalarNode<? extends RAbstractVector, ? extends Object> createIndexedAction(RType type, boolean setListElementAsObject, boolean isReplace) { switch (type) { case Logical: return new WriteLogicalAction(); @@ -378,7 +377,7 @@ abstract class WriteIndexedVectorNode extends Node { } } - private abstract static class WriteIndexedScalarNode<A extends RAbstractVector, V extends RTypedValue> extends Node { + private abstract static class WriteIndexedScalarNode<A extends RAbstractVector, V extends Object> extends Node { final NACheck valueNACheck = NACheck.create(); @@ -483,7 +482,7 @@ abstract class WriteIndexedVectorNode extends Node { } } - private static final class WriteListAction extends WriteIndexedScalarNode<RAbstractListBaseVector, RTypedValue> { + private static final class WriteListAction extends WriteIndexedScalarNode<RAbstractListBaseVector, Object> { private final boolean setListElementAsObject; private final boolean isReplace; @@ -501,7 +500,7 @@ abstract class WriteIndexedVectorNode extends Node { } @Override - void apply(RAbstractListBaseVector leftAccess, Object leftStore, int leftIndex, RTypedValue rightAccess, Object rightStore, int rightIndex) { + void apply(RAbstractListBaseVector leftAccess, Object leftStore, int leftIndex, Object rightAccess, Object rightStore, int rightIndex) { Object rightValue; if (setListElementAsObject) { rightValue = rightAccess; 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 45e05ed3d3c112efe60e6e95a89a678e01251ecb..0fe9a5554b4700a1b893514c8b1549a973a4617f 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 @@ -130720,6 +130720,22 @@ $stringValue [external object] [1] "a" "" "foo" +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAddToList# +#if (length(grep("FastR", R.Version()$version.string)) != 1) { TRUE } else { to <- .fastr.interop.new(.fastr.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); l <- list(); l$foreignobject <- to; identical(to, l$foreignobject) } +[1] TRUE + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAddToList# +#if (length(grep("FastR", R.Version()$version.string)) != 1) { TRUE } else { to <- .fastr.interop.new(.fastr.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); l <- list(1); l$foreignobject <- 1; l$foreignobject <- to; identical(to, l$foreignobject) } +[1] TRUE + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAddToList# +#if (length(grep("FastR", R.Version()$version.string)) != 1) { TRUE } else { to <- .fastr.interop.new(.fastr.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); l <- list(1); l$foreignobject <- to; identical(to, l$foreignobject) } +[1] TRUE + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAddToList# +#if (length(grep("FastR", R.Version()$version.string)) != 1) { TRUE } else { to <- .fastr.interop.new(.fastr.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); l <- list(to); is.list(l) } +[1] TRUE + ##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAllTypes# #if (length(grep("FastR", R.Version()$version.string)) != 1) { "true127a32767214748364792233720368547758071.7976931348623157E3083.4028235E38testString" } else { to <- .fastr.interop.new(.fastr.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); to$allTypesMethod(TRUE,127,"a",32767,2147483647,9223372036854775807,1.7976931348623157E308,3.4028235E38,"testString") } [1] "true127a32767214748364792233720368547758071.7976931348623157E3083.4028235E38testString" diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java index 5d1d166160c6db4a8ccd366c71c83ee9493faeb3..40cf0e7e01f837cc2d2b0e19f54fee9f7dbfe2d6 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java @@ -424,6 +424,14 @@ public class TestJavaInterop extends TestBase { assertEvalFastR(CREATE_TRUFFLE_OBJECT + " " + function + "(to)", expectedOutput); } + @Test + public void testAddToList() { + assertEvalFastR(CREATE_TRUFFLE_OBJECT + " l <- list(to); is.list(l)", "TRUE"); + assertEvalFastR(CREATE_TRUFFLE_OBJECT + " l <- list(); l$foreignobject <- to; identical(to, l$foreignobject)", "TRUE"); + assertEvalFastR(CREATE_TRUFFLE_OBJECT + " l <- list(1); l$foreignobject <- to; identical(to, l$foreignobject)", "TRUE"); + assertEvalFastR(CREATE_TRUFFLE_OBJECT + " l <- list(1); l$foreignobject <- 1; l$foreignobject <- to; identical(to, l$foreignobject)", "TRUE"); + } + @Test public void testAttributes() { assertEvalFastR(CREATE_TRUFFLE_OBJECT + " attributes(to)", "NULL");