diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java index e9748c82908fd0936ef94148042354a528f0b0cc..58653d31ac1260cf5795ed598a7cc9d339a60374 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java @@ -41,6 +41,7 @@ import com.oracle.truffle.api.CompilerDirectives; 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.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.Node; @@ -78,6 +79,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.ops.na.NACheck; +@ImportStatic(RRuntime.class) @RBuiltin(name = "c", kind = PRIMITIVE, parameterNames = {"...", "recursive"}, dispatch = INTERNAL_GENERIC, behavior = PURE) public abstract class Combine extends RBuiltinNode.Arg2 { @@ -110,7 +112,7 @@ public abstract class Combine extends RBuiltinNode.Arg2 { public abstract Object executeCombine(Object value, Object recursive); protected boolean isSimpleArguments(RArgsValuesAndNames args) { - return !signatureHasNames(args.getSignature()) && args.getLength() == 1 && !(args.getArgument(0) instanceof RAbstractVector); + return !signatureHasNames(args.getSignature()) && args.getLength() == 1 && !(args.getArgument(0) instanceof RAbstractVector) && !RRuntime.isForeignObject(args.getArgument(0)); } @Specialization(guards = {"isSimpleArguments(args)", "!recursive"}) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java index 4049261a8a263e7929f019d6c73a1d24f5c99bc4..11cbc9ac724d29fb42f9bf2cc27bff32a31d5ed2 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java @@ -765,7 +765,7 @@ public class FastRInterop { static { Casts casts = new Casts(FromForeignArray.class); - casts.arg("array").mustNotBeMissing(); + casts.arg("array").castForeignObjects(false).mustNotBeMissing(); } private final ConditionProfile isArrayProfile = ConditionProfile.createBinaryProfile(); diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastBuilderTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastBuilderTest.java index ad4f0b46c876189de0c9944a81c4a17bf13b92e4..817a66144fcecafb1cae808b9baca46ef9f8692a 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastBuilderTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastBuilderTest.java @@ -22,6 +22,8 @@ */ package com.oracle.truffle.r.nodes.castsTests; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.java.JavaInterop; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.abstractVectorValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.anyValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asBoolean; @@ -102,12 +104,15 @@ import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.env.REnvironment.NewEnv; import com.oracle.truffle.r.test.generate.FastRSession; +import java.util.Arrays; +import java.util.List; /** * Tests the cast pipelines and also that the samples generation process matches the intended @@ -903,6 +908,30 @@ public class CastBuilderTest { assertCastFail("abc"); } + @Test + public void testCastForeignArray() { + arg.mustBe(integerValue()); + int[] array = new int[]{1, 2, 3}; + Object value = cast(JavaInterop.asTruffleObject(array)); + assertTrue(value instanceof RAbstractIntVector); + } + + @Test + public void testCastJavaIterable() { + arg.mustBe(integerValue()); + List<Integer> list = Arrays.asList(1, 2, 3); + Object value = cast(JavaInterop.asTruffleObject(list)); + assertTrue(value instanceof RAbstractIntVector); + } + + @Test + public void testCastForeignObjectDisabled() { + arg.castForeignObjects(false).mustBe(missingValue().not()); + TruffleObject obj = JavaInterop.asTruffleObject(new int[]{1, 2, 3}); + Object value = cast(obj); + assertTrue(value == obj); + } + /** * Casts given object using the configured pipeline in {@link #arg}. */ diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/PipelineToCastNodeTests.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/PipelineToCastNodeTests.java index 444a877bf6a11d8a738e66673aebfcae3bd9d489..076b9cce21dc530e40ba989bd77d7d2cdffc1bd2 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/PipelineToCastNodeTests.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/PipelineToCastNodeTests.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.nodes.test; +import com.oracle.truffle.r.nodes.builtin.casts.CastForeignNode; import static junit.framework.TestCase.assertTrue; import static org.junit.Assert.assertEquals; @@ -52,27 +53,59 @@ import com.oracle.truffle.r.runtime.env.REnvironment; public class PipelineToCastNodeTests { @Test public void asLogicalVector() { - assertTrue(createPipeline(new CoercionStep<>(RType.Logical, false)) instanceof CastLogicalBaseNode); + // without first cast of foreign objects + CastNode pipeline = createPipeline(new CoercionStep<>(RType.Logical, false), false); + assertTrue(pipeline instanceof CastLogicalBaseNode); + + // with first cast of foreign objects + pipeline = createPipeline(new CoercionStep<>(RType.Logical, false), true); + assertChainedCast(pipeline, CastForeignNode.class, CastLogicalBaseNode.class); } @Test public void asStringVectorFindFirst() { - assertChainedCast(createPipeline(new CoercionStep<>(RType.Character, false).setNext(new FindFirstStep<>("hello", String.class, null))), CastStringBaseNode.class, FindFirstNode.class); - FindFirstNode findFirst = (FindFirstNode) ((ChainedCastNode) createPipeline( - new CoercionStep<>(RType.Character, false).setNext(new FindFirstStep<>("hello", String.class, null)))).getSecondCast(); + PipelineStep<?, ?> steps = new CoercionStep<>(RType.Character, false).setNext(new FindFirstStep<>("hello", String.class, null)); + + // without first cast of foreign objects + CastNode pipeline = createPipeline(steps, false); + assertChainedCast(pipeline, CastStringBaseNode.class, FindFirstNode.class); + + FindFirstNode findFirst = (FindFirstNode) ((ChainedCastNode) pipeline).getSecondCast(); assertEquals("hello", findFirst.getDefaultValue()); + + // with first cast of foreign objects + pipeline = createPipeline(steps, true); + assertChainedCast(pipeline, ChainedCastNode.class, FindFirstNode.class); + + CastNode next = ((ChainedCastNode) pipeline).getFirstCast(); + assertChainedCast(next, CastForeignNode.class, CastStringBaseNode.class); } @Test public void mustBeREnvironmentAsIntegerVectorFindFirst() { - assertChainedCast(createPipeline(new FilterStep<>(new TypeFilter<>(REnvironment.class), null, false).setNext( - new CoercionStep<>(RType.Integer, false).setNext(new FindFirstStep<>("hello", String.class, null)))), ChainedCastNode.class, FindFirstNode.class); - CastNode next = ((ChainedCastNode) createPipeline(new FilterStep<>(new TypeFilter<>(REnvironment.class), null, false).setNext( - new CoercionStep<>(RType.Integer, false).setNext(new FindFirstStep<>("hello", String.class, null))))).getFirstCast(); + PipelineStep<?, ?> steps = new FilterStep<>(new TypeFilter<>(REnvironment.class), null, false).setNext( + new CoercionStep<>(RType.Integer, false).setNext(new FindFirstStep<>("hello", String.class, null))); + + // without first cast of foreign objects + CastNode pipeline = createPipeline(steps, false); + + assertChainedCast(pipeline, ChainedCastNode.class, FindFirstNode.class); + CastNode next = ((ChainedCastNode) pipeline).getFirstCast(); assertChainedCast(next, FilterNode.class, CastIntegerBaseNode.class); - FindFirstNode findFirst = (FindFirstNode) ((ChainedCastNode) createPipeline(new FilterStep<>(new TypeFilter<>(REnvironment.class), null, false).setNext( - new CoercionStep<>(RType.Integer, false).setNext(new FindFirstStep<>("hello", String.class, null))))).getSecondCast(); + + FindFirstNode findFirst = (FindFirstNode) ((ChainedCastNode) pipeline).getSecondCast(); assertEquals("hello", findFirst.getDefaultValue()); + + // with first cast of foreign objects + pipeline = createPipeline(steps, true); + assertChainedCast(pipeline, ChainedCastNode.class, FindFirstNode.class); + + next = ((ChainedCastNode) pipeline).getFirstCast(); + assertChainedCast(next, ChainedCastNode.class, CastIntegerBaseNode.class); + + next = ((ChainedCastNode) next).getFirstCast(); + assertChainedCast(next, CastForeignNode.class, FilterNode.class); + } private static void assertChainedCast(CastNode node, Class<?> expectedFirst, Class<?> expectedSecond) { @@ -81,9 +114,10 @@ public class PipelineToCastNodeTests { assertTrue(expectedSecond.isInstance(((ChainedCastNode) node).getSecondCast())); } - private static CastNode createPipeline(PipelineStep<?, ?> lastStep) { + private static CastNode createPipeline(PipelineStep<?, ?> lastStep, boolean castForeign) { PipelineConfigBuilder configBuilder = new PipelineConfigBuilder("x"); configBuilder.setValueForwarding(false); + configBuilder.setCastForeignObjects(castForeign); return PipelineToCastNode.convert(configBuilder.build(), lastStep, ForwardingAnalysisResult.INVALID); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java index 6896d4cf0c35ad53ab21aa12a96d85cc0b02ebce..3ca986a2bb6fa5c664383b5bf2e67831fe6bd189 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java @@ -29,10 +29,6 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.java.JavaInterop; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.primitive.BinaryMapNode; @@ -51,8 +47,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; -import com.oracle.truffle.r.runtime.interop.ForeignArray2R; -import com.oracle.truffle.r.runtime.interop.ForeignArray2RNodeGen; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.ops.BinaryArithmetic; import com.oracle.truffle.r.runtime.ops.BinaryArithmeticFactory; @@ -63,7 +57,6 @@ import com.oracle.truffle.r.runtime.ops.UnaryArithmeticFactory; * operation is implemented by factory object given as a constructor parameter, e.g. * {@link com.oracle.truffle.r.runtime.ops.BinaryArithmetic.Add} */ -@ImportStatic({RRuntime.class, com.oracle.truffle.api.interop.Message.class}) public abstract class BinaryArithmeticNode extends RBuiltinNode.Arg2 { protected static final int CACHE_LIMIT = 5; @@ -156,68 +149,6 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode.Arg2 { return doLeftNull(right, left, classProfile); } - @Specialization(replaces = "doNumericVectorCached", guards = {"isForeignVector(left, hasSize)", "isNumericVector(right)"}) - @TruffleBoundary - protected Object doForeignLeft(TruffleObject left, Object right, - @SuppressWarnings("unused") @Cached("HAS_SIZE.createNode()") Node hasSize, - @Cached("createForeignArray2R()") ForeignArray2R foreignArray2R, - @Cached("createRecursive()") BinaryArithmeticNode recursive) { - Object o = foreignArray2R.execute(left, true); - return recursive.execute(o, right); - } - - @Specialization(replaces = "doNumericVectorCached", guards = {"isNumericVector(left)", "isForeignVector(right, hasSize)"}) - @TruffleBoundary - protected Object doForeignRight(Object left, TruffleObject right, - @SuppressWarnings("unused") @Cached("HAS_SIZE.createNode()") Node hasSize, - @Cached("createForeignArray2R()") ForeignArray2R foreignArray2R, - @Cached("createRecursive()") BinaryArithmeticNode recursive) { - Object o = foreignArray2R.execute(right, true); - return recursive.execute(left, o); - } - - @Specialization(replaces = "doNumericVectorCached", guards = {"isForeignVector(left, hasSize)", "isForeignVector(right, hasSize)"}) - @TruffleBoundary - protected Object doForeignVector(TruffleObject left, TruffleObject right, - @SuppressWarnings("unused") @Cached("HAS_SIZE.createNode()") Node hasSize, - @Cached("createForeignArray2R()") ForeignArray2R leftForeignArray2R, - @Cached("createForeignArray2R()") ForeignArray2R rightForeignArray2R, - @Cached("createRecursive()") BinaryArithmeticNode recursive) { - Object oLeft = leftForeignArray2R.execute(left, true); - Object oRight = rightForeignArray2R.execute(right, true); - return recursive.execute(oLeft, oRight); - } - - protected ForeignArray2R createForeignArray2R() { - return ForeignArray2RNodeGen.create(); - } - - protected boolean isForeignVector(Object obj, Node hasSize) { - return RRuntime.isForeignObject(obj) && (ForeignAccess.sendHasSize(hasSize, (TruffleObject) obj) || JavaInterop.isJavaObject(Iterable.class, (TruffleObject) obj)); - } - - protected BinaryArithmeticNode createRecursive() { - return BinaryArithmeticNodeGen.create(binary, unary); - } - - @Specialization(guards = {"isForeignVector(right, hasSize)"}) - protected Object doForeignLeftNull(RNull left, TruffleObject right, - @SuppressWarnings("unused") @Cached("HAS_SIZE.createNode()") Node hasSize, - @Cached("createForeignArray2R()") ForeignArray2R foreignArray2R, - @Cached("createRecursive()") BinaryArithmeticNode recursive) { - Object oRight = foreignArray2R.execute(right, true); - return recursive.execute(left, oRight); - } - - @Specialization(guards = {"isForeignVector(left, hasSize)"}) - protected Object doForeignRightNull(TruffleObject left, RNull right, - @SuppressWarnings("unused") @Cached("HAS_SIZE.createNode()") Node hasSize, - @Cached("createForeignArray2R()") ForeignArray2R foreignArray2R, - @Cached("createRecursive()") BinaryArithmeticNode recursive) { - Object oLeft = foreignArray2R.execute(left, true); - return recursive.execute(oLeft, right); - } - @Fallback protected Object doInvalidType(@SuppressWarnings("unused") Object left, @SuppressWarnings("unused") Object right) { throw error(Message.NON_NUMERIC_BINARY); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java index ae3cdfeff6afb55e27e55aefa564646cbad8e700..4aac9d4b03aa25c3b7117f06684dac68da56df95 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java @@ -26,11 +26,8 @@ import com.oracle.truffle.api.CompilerAsserts; 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.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.primitive.BinaryMapNode; import com.oracle.truffle.r.nodes.profile.TruffleBoundaryNode; @@ -57,7 +54,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; -import com.oracle.truffle.r.runtime.interop.ForeignArray2R; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.ops.BinaryLogic; import com.oracle.truffle.r.runtime.ops.BinaryLogic.And; @@ -70,7 +66,6 @@ import com.oracle.truffle.r.runtime.ops.BooleanOperationFactory; * operation is implemented by factory object given as a constructor parameter, e.g. * {@link com.oracle.truffle.r.runtime.ops.BinaryLogic.And}. */ -@ImportStatic({ForeignArray2R.class, com.oracle.truffle.api.interop.Message.class}) public abstract class BinaryBooleanNode extends RBuiltinNode.Arg2 { protected static final int CACHE_LIMIT = 5; @@ -242,17 +237,6 @@ public abstract class BinaryBooleanNode extends RBuiltinNode.Arg2 { return (isRAbstractVector(value) && ((RAbstractVector) value).getLength() == 0); } - @Specialization(guards = {"isForeignVector(left, hasSize) || isForeignVector(right, hasSize)"}) - protected Object doForeignVector(VirtualFrame frame, TruffleObject left, TruffleObject right, - @SuppressWarnings("unused") @Cached("HAS_SIZE.createNode()") Node hasSize, - @Cached("createForeignArray2R()") ForeignArray2R leftForeignArray2R, - @Cached("createForeignArray2R()") ForeignArray2R rightForeignArray2R, - @Cached("createRecursive()") BinaryBooleanNode recursive) { - Object oLeft = leftForeignArray2R.execute(left, true); - Object oRight = rightForeignArray2R.execute(right, true); - return recursive.execute(frame, oLeft, oRight); - } - @Fallback protected Object doInvalidType(@SuppressWarnings("unused") Object left, @SuppressWarnings("unused") Object right) { throw error(Message.OPERATIONS_NUMERIC_LOGICAL_COMPLEX); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/CastForeignNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/CastForeignNode.java new file mode 100644 index 0000000000000000000000000000000000000000..450f30bb90ad4b7d6600b949ccf308d7a3e47e61 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/CastForeignNode.java @@ -0,0 +1,52 @@ +/* + * 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.builtin.casts; + +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.nodes.unary.CastNode; +import com.oracle.truffle.r.runtime.interop.ForeignArray2R; + +@ImportStatic({ForeignArray2R.class, Message.class}) +public abstract class CastForeignNode extends CastNode { + + protected CastForeignNode() { + } + + @Specialization(guards = {"isForeignVector(obj, hasSize)"}) + protected Object castForeign(TruffleObject obj, + @Cached("HAS_SIZE.createNode()") Node hasSize, + @Cached("createForeignArray2R()") ForeignArray2R foreignArray2R) { + return foreignArray2R.execute(obj, true); + } + + @Fallback + protected Object passThrough(Object x) { + return x; + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineConfig.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineConfig.java index 607f55a25861a11743c224f8c488bb4f2dc0e505..0e487adfd247a494ecf1bfeac924c0813216b5c0 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineConfig.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineConfig.java @@ -35,12 +35,14 @@ public class PipelineConfig { private final String argumentName; private final MessageData defaultError; private final MessageData defaultWarning; - private boolean valueForwarding; + private final boolean valueForwarding; + private final boolean castForeign; - public PipelineConfig(String argumentName, MessageData defaultError, MessageData defaultWarning, boolean valueForwarding) { + public PipelineConfig(String argumentName, MessageData defaultError, MessageData defaultWarning, boolean valueForwarding, boolean castForeign) { this.defaultError = defaultError; this.defaultWarning = defaultWarning; this.valueForwarding = valueForwarding; + this.castForeign = castForeign; this.argumentName = argumentName; } @@ -63,4 +65,8 @@ public class PipelineConfig { public boolean getValueForwarding() { return valueForwarding; } + + public boolean getCastForeign() { + return castForeign; + } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java index 79aa7369fffad8721bea07bc47382e7d6ceeecda..12aaa0ec1f3df2f353fbc0bc633110f87b42698f 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java @@ -116,7 +116,9 @@ public final class PipelineToCastNode { boolean singleMapStep = firstStepIn.getNext() == null && firstStepIn instanceof MapIfStep; PipelineStep<?, ?> firstStep = singleMapStep ? ((MapIfStep<?, ?>) firstStepIn).withoutReturns() : firstStepIn; - Supplier<CastNode> originalPipelineFactory = () -> convert(firstStep, new CastNodeFactory(config.getDefaultError(), config.getDefaultWarning(), config.getDefaultDefaultMessage())); + CastNode firstCastNode = config.getCastForeign() ? CastForeignNodeGen.create() : null; + Supplier<CastNode> originalPipelineFactory = () -> convert(firstCastNode, firstStep, + new CastNodeFactory(config.getDefaultError(), config.getDefaultWarning(), config.getDefaultDefaultMessage())); if (!config.getValueForwarding()) { return originalPipelineFactory.get(); @@ -132,12 +134,12 @@ public final class PipelineToCastNode { /** * Converts chain of pipeline steps to cast nodes. */ - private static CastNode convert(PipelineStep<?, ?> firstStep, PipelineStepVisitor<CastNode> nodeFactory) { + private static CastNode convert(CastNode firstCastNode, PipelineStep<?, ?> firstStep, PipelineStepVisitor<CastNode> nodeFactory) { if (firstStep == null) { return null; } - CastNode prevCastNode = null; + CastNode prevCastNode = firstCastNode; PipelineStep<?, ?> currCastStep = firstStep; while (currCastStep != null) { CastNode node = currCastStep.accept(nodeFactory, prevCastNode); @@ -145,8 +147,7 @@ public final class PipelineToCastNode { if (prevCastNode == null) { prevCastNode = node; } else { - CastNode finalPrevCastNode = prevCastNode; - prevCastNode = new ChainedCastNode(finalPrevCastNode, node, currCastStep.getNext() == null); + prevCastNode = new ChainedCastNode(prevCastNode, node, currCastStep.getNext() == null); } } @@ -261,8 +262,8 @@ public final class PipelineToCastNode { public CastNode visit(MapIfStep<?, ?> step, CastNode previous) { @SuppressWarnings("unchecked") ArgumentFilter<Object, Object> condition = (ArgumentFilter<Object, Object>) ArgumentFilterFactoryImpl.INSTANCE.createFilter(step.getFilter()); - CastNode trueCastNode = PipelineToCastNode.convert(step.getTrueBranch(), this); - CastNode falseCastNode = PipelineToCastNode.convert(step.getFalseBranch(), this); + CastNode trueCastNode = PipelineToCastNode.convert(null, step.getTrueBranch(), this); + CastNode falseCastNode = PipelineToCastNode.convert(null, step.getFalseBranch(), this); return ConditionalMapNode.create(condition, trueCastNode, falseCastNode, ResultForArg.TRUE.equals(step.getFilter().resultForNull()), ResultForArg.TRUE.equals(step.getFilter().resultForMissing()), step.isReturns()); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineConfigBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineConfigBuilder.java index 9fa3ffa3109970c15cc104782385cd2fe69235d6..8d2e7119bc9a5a976ae6b160000aa00a8cd1035a 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineConfigBuilder.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineConfigBuilder.java @@ -39,6 +39,7 @@ public final class PipelineConfigBuilder { private MessageData defaultWarning; private boolean valueForwarding = true; + private boolean castForeign = true; public PipelineConfigBuilder(String argumentName) { this.argumentName = argumentName; @@ -47,7 +48,7 @@ public final class PipelineConfigBuilder { } public PipelineConfig build() { - return new PipelineConfig(argumentName, defaultError, defaultWarning, valueForwarding); + return new PipelineConfig(argumentName, defaultError, defaultWarning, valueForwarding, castForeign); } void setDefaultError(MessageData defaultError) { @@ -62,4 +63,9 @@ public final class PipelineConfigBuilder { this.valueForwarding = flag; return this; } + + public PipelineConfigBuilder setCastForeignObjects(boolean flag) { + this.castForeign = flag; + return this; + } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java index 3c959e0bb414bd8e34556e3c3ebfff77377daf82..b54e004571f27eb45d2fb3102d9ea09169466e58 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java @@ -96,6 +96,18 @@ public final class PreinitialPhaseBuilder extends InitialPhaseBuilder<Object> { return this; } + /** + * Determines whether foreign arrays are implicitly casted to a R vector/list or not. <br> + * The default setting is <code>true</code>. + * + * @param flag + * @return + */ + public PreinitialPhaseBuilder castForeignObjects(boolean flag) { + pipelineBuilder().getPipelineConfig().setCastForeignObjects(flag); + return this; + } + public PreinitialPhaseBuilder defaultWarning(Message message, Object... args) { pipelineBuilder().getPipelineConfig().setDefaultWarning(new MessageData(message, args)); return this; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java index f90e615ee6ac2e7ea4b56b8ef5ff0c7f37804c84..88151421902d9518fbfeb23035b5ca4e27bcce3e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java @@ -26,9 +26,7 @@ import java.util.function.IntFunction; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.RError; @@ -48,12 +46,9 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; -import com.oracle.truffle.r.runtime.interop.ForeignArray2R; -import com.oracle.truffle.r.runtime.interop.ForeignArray2RNodeGen; import com.oracle.truffle.r.runtime.ops.na.NACheck; import com.oracle.truffle.r.runtime.ops.na.NAProfile; -@ImportStatic(RRuntime.class) public abstract class CastComplexNode extends CastBaseNode { private final NACheck naCheck = NACheck.create(); @@ -269,22 +264,6 @@ public abstract class CastComplexNode extends CastBaseNode { return ret; } - @Specialization(guards = "isForeignObject(obj)") - protected RComplexVector doForeignObject(TruffleObject obj, - @Cached("createForeignArray2RNode()") ForeignArray2R foreignArray2R) { - Object o = foreignArray2R.execute(obj, true); - if (!RRuntime.isForeignObject(o)) { - if (o instanceof RComplexVector) { - return (RComplexVector) o; - } - o = castComplexRecursive(o); - if (o instanceof RComplexVector) { - return (RComplexVector) o; - } - } - throw error(RError.Message.CANNOT_COERCE_EXTERNAL_OBJECT_TO_VECTOR, "vector"); - } - public static CastComplexNode create() { return CastComplexNodeGen.create(true, true, true); } @@ -296,8 +275,4 @@ public abstract class CastComplexNode extends CastBaseNode { public static CastComplexNode createNonPreserving() { return CastComplexNodeGen.create(false, false, false); } - - protected ForeignArray2R createForeignArray2RNode() { - return ForeignArray2RNodeGen.create(); - } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java index 1f4c55c3899a02c425977270b76ca47e747c0d20..c426860c0f999a558a6de930d99a750e1133cec7 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java @@ -22,14 +22,10 @@ */ package com.oracle.truffle.r.nodes.unary; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; 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.RDataFactory; import com.oracle.truffle.r.runtime.data.RExpression; @@ -38,14 +34,9 @@ import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; -import com.oracle.truffle.r.runtime.interop.ForeignArray2R; -import com.oracle.truffle.r.runtime.interop.ForeignArray2RNodeGen; -@ImportStatic(RRuntime.class) public abstract class CastExpressionNode extends CastBaseNode { - @Child private CastExpressionNode recursiveCastExpression; - public abstract Object executeExpression(Object o); protected CastExpressionNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { @@ -113,16 +104,6 @@ public abstract class CastExpressionNode extends CastBaseNode { } } - @Specialization(guards = "isForeignObject(obj)") - protected RExpression doForeignObject(TruffleObject obj, - @Cached("createForeignArray2RNode()") ForeignArray2R foreignArray2R) { - Object o = foreignArray2R.execute(obj, true); - if (!RRuntime.isForeignObject(o)) { - return (RExpression) castExpressionRecursive(o); - } - throw error(RError.Message.CANNOT_COERCE_EXTERNAL_OBJECT_TO_VECTOR, "vector"); - } - private static RExpression create(Object obj) { return RDataFactory.createExpression(new Object[]{obj}); } @@ -137,16 +118,4 @@ public abstract class CastExpressionNode extends CastBaseNode { public static CastExpressionNode createNonPreserving() { return CastExpressionNodeGen.create(false, false, false); } - - protected ForeignArray2R createForeignArray2RNode() { - return ForeignArray2RNodeGen.create(); - } - - private Object castExpressionRecursive(Object o) { - if (recursiveCastExpression == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - recursiveCastExpression = insert(CastExpressionNodeGen.create(preserveNames(), preserveDimensions(), preserveAttributes())); - } - return recursiveCastExpression.executeExpression(o); - } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java index 181c0dc8e48ebbb798e4384366c9cd7cfdfc77b9..c66438279a68fe416dead3725adc170253c3d9ac 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java @@ -24,9 +24,7 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.RError; @@ -45,12 +43,9 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; -import com.oracle.truffle.r.runtime.interop.ForeignArray2R; -import com.oracle.truffle.r.runtime.interop.ForeignArray2RNodeGen; import com.oracle.truffle.r.runtime.ops.na.NACheck; import com.oracle.truffle.r.runtime.ops.na.NAProfile; -@ImportStatic(RRuntime.class) public abstract class CastRawNode extends CastBaseNode { private final NACheck naCheck = NACheck.create(); @@ -317,22 +312,6 @@ public abstract class CastRawNode extends CastBaseNode { return result; } - @Specialization(guards = "isForeignObject(obj)") - protected RRawVector doForeignObject(TruffleObject obj, - @Cached("createForeignArray2RNode()") ForeignArray2R foreignArray2R) { - Object o = foreignArray2R.execute(obj, true); - if (!RRuntime.isForeignObject(o)) { - if (o instanceof RRawVector) { - return (RRawVector) o; - } - o = castRawRecursive(o); - if (o instanceof RRawVector) { - return (RRawVector) o; - } - } - throw error(RError.Message.CANNOT_COERCE_EXTERNAL_OBJECT_TO_VECTOR, "vector"); - } - public static CastRawNode createForRFFI(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { return CastRawNodeGen.create(preserveNames, preserveDimensions, preserveAttributes, true); } @@ -340,8 +319,4 @@ public abstract class CastRawNode extends CastBaseNode { public static CastRawNode createNonPreserving() { return CastRawNodeGen.create(false, false, false); } - - protected ForeignArray2R createForeignArray2RNode() { - return ForeignArray2RNodeGen.create(); - } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java index 047b9987bafdd659e8473a37c9af06d6b1cde0b0..2b45b6639ae5045f8d4941d354b0fc0bf958e45a 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java @@ -24,13 +24,9 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.TruffleObject; 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.RType; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; @@ -41,14 +37,10 @@ import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; -import com.oracle.truffle.r.runtime.interop.ForeignArray2R; -import com.oracle.truffle.r.runtime.interop.ForeignArray2RNodeGen; -@ImportStatic(RRuntime.class) public abstract class CastSymbolNode extends CastBaseNode { @Child private ToStringNode toString = ToStringNodeGen.create(); - @Child private CastSymbolNode recursiveCastSymbol; protected CastSymbolNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { this(preserveNames, preserveDimensions, preserveAttributes, false); @@ -140,16 +132,6 @@ public abstract class CastSymbolNode extends CastBaseNode { return RDataFactory.createSymbolInterned(s); } - @Specialization(guards = "isForeignObject(obj)") - protected RSymbol doForeignObject(TruffleObject obj, - @Cached("createForeignArray2RNode()") ForeignArray2R foreignArray2R) { - Object o = foreignArray2R.execute(obj, true); - if (!RRuntime.isForeignObject(o)) { - return (RSymbol) castSymbolRecursive(o); - } - throw error(RError.Message.CANNOT_COERCE_EXTERNAL_OBJECT_TO_VECTOR, "vector"); - } - @Override protected Object doOtherRFFI(Object mappedValue) { if (mappedValue instanceof RList) { @@ -166,16 +148,4 @@ public abstract class CastSymbolNode extends CastBaseNode { public static CastSymbolNode createNonPreserving() { return CastSymbolNodeGen.create(false, false, false); } - - protected ForeignArray2R createForeignArray2RNode() { - return ForeignArray2RNodeGen.create(); - } - - private Object castSymbolRecursive(Object o) { - if (recursiveCastSymbol == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - recursiveCastSymbol = insert(CastSymbolNodeGen.create(preserveNames(), preserveDimensions(), preserveAttributes())); - } - return recursiveCastSymbol.executeSymbol(o); - } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java index ce65ed44e29023665f06ee0f4e4741eba3c24e63..1f0892d7285603e2bf2950d8ba38a5b7df910ed3 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java @@ -26,11 +26,7 @@ import com.oracle.truffle.api.CompilerDirectives; 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.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.Message; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.nodes.primitive.UnaryMapNode; import com.oracle.truffle.r.nodes.profile.TruffleBoundaryNode; import com.oracle.truffle.r.runtime.RError; @@ -41,12 +37,10 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; -import com.oracle.truffle.r.runtime.interop.ForeignArray2R; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.ops.UnaryArithmetic; import com.oracle.truffle.r.runtime.ops.UnaryArithmeticFactory; -@ImportStatic({ForeignArray2R.class, Message.class}) public abstract class UnaryArithmeticNode extends UnaryNode { protected final UnaryArithmeticFactory unary; @@ -101,19 +95,6 @@ public abstract class UnaryArithmeticNode extends UnaryNode { return this; } - @Specialization(guards = {"isForeignVector(obj, hasSize)"}) - protected Object doForeignVector(TruffleObject obj, - @SuppressWarnings("unused") @Cached("HAS_SIZE.createNode()") Node hasSize, - @Cached("createForeignArray2R()") ForeignArray2R foreignArray2R, - @Cached("createRecursive()") UnaryArithmeticNode recursive) { - Object vec = foreignArray2R.execute(obj, true); - return recursive.execute(vec); - } - - protected UnaryArithmeticNode createRecursive() { - return UnaryArithmeticNodeGen.create(unary); - } - @Fallback protected Object invalidArgType(Object operand) { CompilerDirectives.transferToInterpreter(); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java index 8d62b74ba44e9abf2dd02b38056682ab5978a462..9a75f0c138bc3483162f99115b8bca3264901fc6 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java @@ -191,7 +191,10 @@ public abstract class ForeignArray2R extends RBaseNode { } /** - * Coverts the elements collected from a foreign array or java iterable into a vector or list. + * Converts the elements collected from a foreign array or java iterable into a vector or list. + * + * @param ce + * @return */ public static RAbstractVector asAbstractVector(CollectedElements ce) { InteropTypeCheck.RType type = ce.typeCheck.getType(); 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 9bf9e9368f2f318dbd3078f5b7d4591361adb640..e5c39e73442c2e5fb0170cdc5c7b44eb72731bc8 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 @@ -132996,9 +132996,9 @@ Error in as.character(to) : no method for coercing this external object to a vector ##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX# -#if (!any(R.version$engine == "FastR")) { cat('Error in as.complex(to) :', '<<<NEWLINE>>>', ' no method for coercing this external object to a vector', '<<<NEWLINE>>>') } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.complex(to); } +#if (!any(R.version$engine == "FastR")) { cat('Error in as.complex(to) :', '<<<NEWLINE>>>', ' cannot coerce type \'truffleobject\' to vector of type \'complex\'', '<<<NEWLINE>>>') } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.complex(to); } Error in as.complex(to) : - no method for coercing this external object to a vector + cannot coerce type 'truffleobject' to vector of type 'complex' ##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX# #if (!any(R.version$engine == "FastR")) { cat('Error in as.double(to) :', '<<<NEWLINE>>>', ' no method for coercing this external object to a vector', '<<<NEWLINE>>>') } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.double(to); } @@ -133021,9 +133021,9 @@ Error in as.logical(to) : no method for coercing this external object to a vector ##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX# -#if (!any(R.version$engine == "FastR")) { cat('Error in as.raw(to) :', '<<<NEWLINE>>>', ' no method for coercing this external object to a vector', '<<<NEWLINE>>>') } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.raw(to); } +#if (!any(R.version$engine == "FastR")) { cat('Error in as.raw(to) :', '<<<NEWLINE>>>', ' cannot coerce type \'truffleobject\' to vector of type \'raw\'', '<<<NEWLINE>>>') } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.raw(to); } Error in as.raw(to) : - no method for coercing this external object to a vector + cannot coerce type 'truffleobject' to vector of type 'raw' ##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX# #if (!any(R.version$engine == "FastR")) { cat('Error in as.symbol(to) :', '<<<NEWLINE>>>', ' no method for coercing this external object to a vector', '<<<NEWLINE>>>') } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.symbol(to); } @@ -133051,54 +133051,206 @@ Error in attr(to, which = "a") : external object cannot be attributed #if (!any(R.version$engine == "FastR")) { "com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass" } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); to$classAsArg(new.java.class(com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass)) } [1] "com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass" -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# -#if (!any(R.version$engine == "FastR")) { 'interopt.byte' } else { class(c(as.external.byte(123))) } -[1] "interopt.byte" - -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# -#if (!any(R.version$engine == "FastR")) { 'list' } else { class(c(1, as.external.byte(123))) } +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { 'list' } else { tc <- new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'); t <- new.external(tc); t1 <- new.external(tc); class(c(t, t1)) } [1] "list" -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# -#if (!any(R.version$engine == "FastR")) { 'list' } else { class(c(as.external.byte(123), 1)) } +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { 'list' } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); class(c(1, t)) } [1] "list" -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# -#if (!any(R.version$engine == "FastR")) { 'list' } else { class(c(as.external.byte(123), as.external.byte(234))) } +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { 'list' } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); class(c(t, 1)) } [1] "list" -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# -#if (!any(R.version$engine == "FastR")) { 'list' } else { tc <- new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'); t <- new.external(tc); t1 <- new.external(tc); class(c(t, t1)) } +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { 'list' } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); class(c(to)) } [1] "list" -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# -#if (!any(R.version$engine == "FastR")) { 'list' } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); class(c(1, t)) } -[1] "list" +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c("1","2","3") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listStringInt) } +[1] "1" "2" "3" -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# -#if (!any(R.version$engine == "FastR")) { 'list' } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); class(c(t, 1)) } -[1] "list" +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c("1","2","3","1","2","3") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listStringInt, to$listStringInt) } +[1] "1" "2" "3" "1" "2" "3" -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# -#if (!any(R.version$engine == "FastR")) { 'truffle.object' } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); class(c(to)) } -[1] "truffle.object" +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c("TRUE","TRUE","FALSE") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listStringBoolean) } +[1] "TRUE" "TRUE" "FALSE" + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c("TRUE","TRUE","FALSE","TRUE","TRUE","FALSE") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listStringBoolean, to$listStringBoolean) } +[1] "TRUE" "TRUE" "FALSE" "TRUE" "TRUE" "FALSE" -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes#Ignored.Unimplemented# +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c("a","b","c") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldCharArray) } +[1] "a" "b" "c" + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# #if (!any(R.version$engine == "FastR")) { c("a","b","c") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldStringArray) } [1] "a" "b" "c" -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes#Ignored.Unimplemented# +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c("a","b","c") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listChar) } +[1] "a" "b" "c" + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# #if (!any(R.version$engine == "FastR")) { c("a","b","c") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listString) } [1] "a" "b" "c" -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# -#if (!any(R.version$engine == "FastR")) { c('a', 'b', 'c', 'a', 'b', 'c') } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldStringArray, to$fieldStringArray) } +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c("a","b","c","a","b","c") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldCharArray, to$fieldCharArray) } [1] "a" "b" "c" "a" "b" "c" -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# -#if (!any(R.version$engine == "FastR")) { c('a', 'b', 'c', 'a', 'b', 'c') } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listString, to$listString) } +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c("a","b","c","a","b","c") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldStringArray, to$fieldStringArray) } +[1] "a" "b" "c" "a" "b" "c" + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c("a","b","c","a","b","c") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listChar, to$listChar) } +[1] "a" "b" "c" "a" "b" "c" + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c("a","b","c","a","b","c") } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listString, to$listString) } [1] "a" "b" "c" "a" "b" "c" +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c() } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listEmpty) } +NULL + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c() } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listEmpty, to$listEmpty) } +NULL + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldByteArray) } +[1] 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldIntegerArray) } +[1] 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldLongArray) } +[1] 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldShortArray) } +[1] 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listByte) } +[1] 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listInteger) } +[1] 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listLong) } +[1] 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listShort) } +[1] 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3,1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldByteArray, to$fieldByteArray) } +[1] 1 2 3 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3,1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldIntegerArray, to$fieldIntegerArray) } +[1] 1 2 3 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3,1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldLongArray, to$fieldLongArray) } +[1] 1 2 3 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3,1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldShortArray, to$fieldShortArray) } +[1] 1 2 3 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3,1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listByte, to$listByte) } +[1] 1 2 3 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3,1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listInteger, to$listInteger) } +[1] 1 2 3 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3,1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listLong, to$listLong) } +[1] 1 2 3 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1,2,3,1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listShort, to$listShort) } +[1] 1 2 3 1 2 3 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1.1,2.1,3.1) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldDoubleArray) } +[1] 1.1 2.1 3.1 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1.1,2.1,3.1) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldFloatArray) } +[1] 1.1 2.1 3.1 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1.1,2.1,3.1) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listDouble) } +[1] 1.1 2.1 3.1 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1.1,2.1,3.1) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listFloat) } +[1] 1.1 2.1 3.1 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1.1,2.1,3.1,1.1,2.1,3.1) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldDoubleArray, to$fieldDoubleArray) } +[1] 1.1 2.1 3.1 1.1 2.1 3.1 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1.1,2.1,3.1,1.1,2.1,3.1) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldFloatArray, to$fieldFloatArray) } +[1] 1.1 2.1 3.1 1.1 2.1 3.1 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1.1,2.1,3.1,1.1,2.1,3.1) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listDouble, to$listDouble) } +[1] 1.1 2.1 3.1 1.1 2.1 3.1 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(1.1,2.1,3.1,1.1,2.1,3.1) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listFloat, to$listFloat) } +[1] 1.1 2.1 3.1 1.1 2.1 3.1 + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(TRUE,FALSE,TRUE) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldBooleanArray) } +[1] TRUE FALSE TRUE + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(TRUE,FALSE,TRUE) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listBoolean) } +[1] TRUE FALSE TRUE + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(TRUE,FALSE,TRUE,TRUE,FALSE,TRUE) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$fieldBooleanArray, to$fieldBooleanArray) } +[1] TRUE FALSE TRUE TRUE FALSE TRUE + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineForeignObjects# +#if (!any(R.version$engine == "FastR")) { c(TRUE,FALSE,TRUE,TRUE,FALSE,TRUE) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); c(to$listBoolean, to$listBoolean) } +[1] TRUE FALSE TRUE TRUE FALSE TRUE + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# +#if (!any(R.version$engine == "FastR")) { 'interopt.byte' } else { class(c(as.external.byte(123))) } +[1] "interopt.byte" + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# +#if (!any(R.version$engine == "FastR")) { 'list' } else { class(c(1, as.external.byte(123))) } +[1] "list" + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# +#if (!any(R.version$engine == "FastR")) { 'list' } else { class(c(as.external.byte(123), 1)) } +[1] "list" + +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testCombineInteropTypes# +#if (!any(R.version$engine == "FastR")) { 'list' } else { class(c(as.external.byte(123), as.external.byte(234))) } +[1] "list" + ##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testConvertEmptyList# #if (!any(R.version$engine == "FastR")) { as.character(list()) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.character(to$listEmpty); } character(0) @@ -133516,9 +133668,8 @@ Error in abs(to) : non-numeric argument to mathematical function [1] 1.1 3.1 ##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testForeignUnaryArithmeticReduceOp# -#if (!any(R.version$engine == "FastR")) { cat('Error in min(x, na.rm = na.rm) :', '<<<NEWLINE>>>', ' invalid \'type\' (external object) of argument', '<<<NEWLINE>>>') } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));range(to) } -Error in min(x, na.rm = na.rm) : - invalid 'type' (external object) of argument +#if (!any(R.version$engine == "FastR")) { cat('Error in min(x, na.rm = na.rm) : invalid \'type\' (list) of argument', '<<<NEWLINE>>>') } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));range(to) } +Error in min(x, na.rm = na.rm) : invalid 'type' (list) of argument ##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testForeignVectorArithmeticOp# #if (!any(R.version$engine == "FastR")) { -c(1,2,3) } else { to <- new.external(new.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));-(to$fieldByteArray) } 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 d1c186b4355b8a5f17aa7f23969538dac3a7dbcd..6c62351cee58b76edf2d5d784269bc68e1e485e7 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 @@ -339,17 +339,45 @@ public class TestJavaInterop extends TestBase { assertEvalFastR("class(c(as.external.byte(123), as.external.byte(234)))", "'list'"); assertEvalFastR("class(c(as.external.byte(123), 1))", "'list'"); assertEvalFastR("class(c(1, as.external.byte(123)))", "'list'"); + } + + @Test + public void testCombineForeignObjects() throws IllegalAccessException, IllegalArgumentException { - assertEvalFastR(CREATE_TRUFFLE_OBJECT + " class(c(to))", "'truffle.object'"); + assertEvalFastR(CREATE_TRUFFLE_OBJECT + " class(c(to))", "'list'"); assertEvalFastR("tc <- new.java.class('" + TEST_CLASS + "'); t <- new.external(tc); t1 <- new.external(tc); class(c(t, t1))", "'list'"); assertEvalFastR(CREATE_TRUFFLE_OBJECT + " class(c(1, t))", "'list'"); assertEvalFastR(CREATE_TRUFFLE_OBJECT + " class(c(t, 1))", "'list'"); TestClass t = new TestClass(); - assertEvalFastR(Ignored.Unimplemented, CREATE_TRUFFLE_OBJECT + " c(to$fieldStringArray)", toRVector(t.fieldStringArray, null)); - assertEvalFastR(Ignored.Unimplemented, CREATE_TRUFFLE_OBJECT + " c(to$listString)", toRVector(t.listString, null)); - assertEvalFastR(CREATE_TRUFFLE_OBJECT + " c(to$fieldStringArray, to$fieldStringArray)", "c('a', 'b', 'c', 'a', 'b', 'c')"); - assertEvalFastR(CREATE_TRUFFLE_OBJECT + " c(to$listString, to$listString)", "c('a', 'b', 'c', 'a', 'b', 'c')"); + + testCombineForeignObjects("fieldBooleanArray", t.fieldBooleanArray); + testCombineForeignObjects("fieldByteArray", t.fieldByteArray); + testCombineForeignObjects("fieldCharArray", t.fieldCharArray); + testCombineForeignObjects("fieldDoubleArray", t.fieldDoubleArray); + testCombineForeignObjects("fieldFloatArray", t.fieldFloatArray); + testCombineForeignObjects("fieldIntegerArray", t.fieldIntegerArray); + testCombineForeignObjects("fieldLongArray", t.fieldLongArray); + testCombineForeignObjects("fieldShortArray", t.fieldShortArray); + testCombineForeignObjects("fieldStringArray", t.fieldStringArray); + + testCombineForeignObjects("listBoolean", t.listBoolean); + testCombineForeignObjects("listByte", t.listByte); + testCombineForeignObjects("listChar", t.listChar); + testCombineForeignObjects("listDouble", t.listDouble); + testCombineForeignObjects("listFloat", t.listFloat); + testCombineForeignObjects("listInteger", t.listInteger); + testCombineForeignObjects("listLong", t.listLong); + testCombineForeignObjects("listShort", t.listShort); + testCombineForeignObjects("listString", t.listString); + testCombineForeignObjects("listStringInt", t.listStringInt); + testCombineForeignObjects("listStringBoolean", t.listStringBoolean); + testCombineForeignObjects("listEmpty", t.listEmpty); + } + + private void testCombineForeignObjects(String field, Object fieldObject) { + assertEvalFastR(CREATE_TRUFFLE_OBJECT + " c(to$" + field + ")", toRVector(fieldObject, null)); + assertEvalFastR(CREATE_TRUFFLE_OBJECT + " c(to$" + field + ", to$" + field + ")", c(fieldObject, fieldObject)); } @Test @@ -837,19 +865,19 @@ public class TestJavaInterop extends TestBase { @Test public void testAsXXX() throws IllegalArgumentException, IllegalAccessException { - testAsXXX("as.character"); - testAsXXX("as.complex"); - testAsXXX("as.double"); - testAsXXX("as.expression"); - testAsXXX("as.integer"); - testAsXXX("as.logical"); - testAsXXX("as.raw"); - testAsXXX("as.symbol"); - testAsXXX("as.vector"); + testAsXXX("as.character", "character"); + testAsXXX("as.complex", "complex"); + testAsXXX("as.double", "double"); + testAsXXX("as.expression", "expression"); + testAsXXX("as.integer", "integer"); + testAsXXX("as.logical", "logical"); + testAsXXX("as.raw", "raw"); + testAsXXX("as.symbol", "symbol"); + testAsXXX("as.vector", null); // TODO more tests } - public void testAsXXX(String asXXX) throws IllegalArgumentException, IllegalAccessException { + public void testAsXXX(String asXXX, String type) throws IllegalArgumentException, IllegalAccessException { TestClass t = new TestClass(); Field[] fields = t.getClass().getDeclaredFields(); @@ -938,9 +966,11 @@ public class TestJavaInterop extends TestBase { } if (asXXX.equals("as.expression")) { - assertEvalFastR(Output.IgnoreErrorContext, CREATE_TRUFFLE_OBJECT + asXXX + "(to);", errorIn("" + asXXX + "(to)", "no method for coercing this external object to a vector")); + assertEvalFastR(Output.IgnoreErrorContext, CREATE_TRUFFLE_OBJECT + asXXX + "(to);", errorIn(asXXX + "(to)", "no method for coercing this external object to a vector")); + } else if (asXXX.equals("as.raw") || asXXX.equals("as.complex")) { + assertEvalFastR(CREATE_TRUFFLE_OBJECT + asXXX + "(to);", errorIn(asXXX + "(to)", "cannot coerce type 'truffleobject' to vector of type '" + type + "'")); } else { - assertEvalFastR(CREATE_TRUFFLE_OBJECT + asXXX + "(to);", errorIn("" + asXXX + "(to)", "no method for coercing this external object to a vector")); + assertEvalFastR(CREATE_TRUFFLE_OBJECT + asXXX + "(to);", errorIn(asXXX + "(to)", "no method for coercing this external object to a vector")); } } @@ -1251,7 +1281,7 @@ public class TestJavaInterop extends TestBase { assertEvalFastR(CREATE_TRUFFLE_OBJECT + "range(to$listStringInt)", "c('1', '3')"); assertEvalFastR(CREATE_TRUFFLE_OBJECT + "range(to$listChar)", "c('a', 'c')"); - assertEvalFastR(CREATE_TRUFFLE_OBJECT + "range(to)", errorIn("min(x, na.rm = na.rm)", "invalid 'type' (external object) of argument")); + assertEvalFastR(CREATE_TRUFFLE_OBJECT + "range(to)", errorIn("min(x, na.rm = na.rm)", "invalid 'type' (list) of argument")); } private String getRValue(Object value) { @@ -1301,23 +1331,36 @@ public class TestJavaInterop extends TestBase { } private String toRVector(Object o, String asXXX) { + return toRVector(list(o), asXXX); + } + + private String toRVector(Object[] l, String asXXX) { + return toRVector(Arrays.asList(l), asXXX); + } + + private String c(Object a1, Object a2) { + List<Object> l = new ArrayList<>(); + List<?> l1 = list(a1); + List<?> l2 = list(a2); + l.addAll(l1); + l.addAll(l2); + return toRVector(l, null); + } + + private List<?> list(Object o) { if (o.getClass().isArray()) { List<Object> l = new ArrayList<>(); for (int i = 0; i < Array.getLength(o); i++) { l.add(Array.get(o, i)); } - return toRVector(l, asXXX); + return l; } else if (o instanceof List) { - return toRVector((List<?>) o, asXXX); + return (List<?>) o; } Assert.fail(o + " should have been an array or list"); return null; } - private String toRVector(Object[] l, String asXXX) { - return toRVector(Arrays.asList(l), asXXX); - } - private String toRVector(List<?> l, String asXXX) { StringBuilder sb = new StringBuilder(); if (asXXX != null) {