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 0a63fd0fac65179d8f49c05307d3fb10b0147caa..5212cec1c120efb55f0b211612033bfadf9836e6 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 @@ -23,11 +23,14 @@ package com.oracle.truffle.r.nodes.binary; import com.oracle.truffle.api.CompilerAsserts; +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.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.r.nodes.attributes.CopyAttributesNode; +import com.oracle.truffle.r.nodes.attributes.CopyAttributesNodeGen; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.primitive.BinaryMapNode; import com.oracle.truffle.r.nodes.profile.TruffleBoundaryNode; @@ -74,6 +77,8 @@ public abstract class BinaryBooleanNode extends RBuiltinNode.Arg2 { protected final BooleanOperationFactory factory; + @Child private CopyAttributesNode copyAttributes; + BinaryBooleanNode(BooleanOperationFactory factory) { this.factory = factory; } @@ -172,23 +177,33 @@ public abstract class BinaryBooleanNode extends RBuiltinNode.Arg2 { @Cached("createRecursive()") BinaryBooleanNode recursive) { Object recursiveLeft = left; if (isRAbstractListVector(left)) { - recursiveLeft = castListToAtomic((RAbstractListBaseVector) left, cast, right.getRType()); + if (copyAttributes == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + copyAttributes = insert(CopyAttributesNodeGen.create(true)); + } + recursiveLeft = castListToAtomic((RAbstractListBaseVector) left, cast, right.getRType(), copyAttributes); } Object recursiveRight = right; if (isRAbstractListVector(right)) { - recursiveRight = castListToAtomic((RAbstractListBaseVector) right, cast, left.getRType()); + if (copyAttributes == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + copyAttributes = insert(CopyAttributesNodeGen.create(true)); + } + recursiveRight = castListToAtomic((RAbstractListBaseVector) right, cast, left.getRType(), copyAttributes); } return recursive.execute(frame, recursiveLeft, recursiveRight); } @TruffleBoundary - private static Object castListToAtomic(RAbstractListBaseVector source, CastTypeNode cast, RType type) { + private static Object castListToAtomic(RAbstractListBaseVector source, CastTypeNode cast, RType type, CopyAttributesNode copyAttributes) { RVector<?> result = type.create(source.getLength(), false); Object store = result.getInternalStore(); for (int i = 0; i < source.getLength(); i++) { Object value = source.getDataAt(i); if (type == RType.Character) { - value = RDeparse.deparse(value); + if (!(value instanceof String)) { + value = RDeparse.deparse(value); + } ((RStringVector) result).setDataAt(store, i, (String) value); } else { value = cast.execute(value, type); @@ -221,6 +236,9 @@ public abstract class BinaryBooleanNode extends RBuiltinNode.Arg2 { } } } + if (copyAttributes != null) { + copyAttributes.execute(result, result, source.getLength(), source, source.getLength()); + } return result; } 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 ebb6146027fc08c38156273fb26a8d2fafc90991..0d6e860fef2419500ad017e4418d5e81ab38a8ac 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 @@ -41799,6 +41799,46 @@ Error in numeric(0):numeric(0) : argument of length 0 Error in Ops.factor(factor(c("a", "b", "c")), factor(c(1, 2, 3))) : level sets of factors are different +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testEqualsList# +#{ l <- list(an='a', bn='b', 3, 4); 'a' == l } + an bn + TRUE FALSE FALSE FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testEqualsList# +#{ l <- list(an='a', bn='b', 3, 4); l == 'a' } + an bn + TRUE FALSE FALSE FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testEqualsList# +#{ l <- list(an=1, bn=2, 3, 4); 1 == l } + an bn + TRUE FALSE FALSE FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testEqualsList# +#{ l <- list(an=1, bn=2, 3, 4); l == 1 } + an bn + TRUE FALSE FALSE FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testEqualsList# +#{ l <- list(an=1L, bn=2L, 3, 4); 1 == l } + an bn + TRUE FALSE FALSE FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testEqualsList# +#{ l <- list(an=1L, bn=2L, 3, 4); l == 1 } + an bn + TRUE FALSE FALSE FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testEqualsList# +#{ l <- list(an=T, bn=F, T, F); T == l } + an bn + TRUE FALSE TRUE FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testEqualsList# +#{ l <- list(an=T, bn=F, T, F); l == T } + an bn + TRUE FALSE TRUE FALSE + ##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testIn# #{ "hello" %in% c("I", "say", "hello", "world") } [1] TRUE diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java index d5454e3d33b83845c5902346709a439527322809..c5b231862d5e112c830d8340c99401e6f2bbde44 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java @@ -4,7 +4,7 @@ * http://www.gnu.org/licenses/gpl-2.0.html * * Copyright (c) 2012-2014, Purdue University - * Copyright (c) 2013, 2017, Oracle and/or its affiliates + * Copyright (c) 2013, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -2067,4 +2067,16 @@ public class TestBuiltin_operators extends TestBase { assertEval(template("%0:%1", parameters, parameters)); assertEval(template("typeof(%0:%1)", parameters, parameters)); } + + @Test + public void testEqualsList() { + assertEval("{ l <- list(an=1, bn=2, 3, 4); l == 1 }"); + assertEval("{ l <- list(an=1, bn=2, 3, 4); 1 == l }"); + assertEval("{ l <- list(an=1L, bn=2L, 3, 4); l == 1 }"); + assertEval("{ l <- list(an=1L, bn=2L, 3, 4); 1 == l }"); + assertEval("{ l <- list(an='a', bn='b', 3, 4); l == 'a' }"); + assertEval("{ l <- list(an='a', bn='b', 3, 4); 'a' == l }"); + assertEval("{ l <- list(an=T, bn=F, T, F); l == T }"); + assertEval("{ l <- list(an=T, bn=F, T, F); T == l }"); + } }