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.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java index 2226824b9fc6c9b2e58a01a580589c10b745f1cc..6adae8c519e9635b56f0fd13b0c170c8475d49a6 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java @@ -323,6 +323,7 @@ public final class RError extends RuntimeException implements TruffleException { */ GENERIC("%s"), TOO_SHORT("'%s' is too short"), + CONVERTED_FROM_WARNING("(converted from warning) %s"), INVALID_DATA_OF_TYPE_TOO_SHORT("invalid data of mode '%s' (too short)"), VECTOR_SIZE_TOO_LARGE("vector size specified is too large"), ARG_RECYCYLED("an argument will be fractionally recycled"), diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java index 3dd9273a2bd84c517c1597ef00797ba2781cd5d9..51d1e1e52ae6956275c16e6fd62b0d46d95ce34f 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java @@ -615,12 +615,6 @@ public class RErrorHandling { warningCallInvoke(call, warningMessage); } - static void errorcall(boolean showCall, RBaseNode callObj, Message msg, Object... args) { - Object call = showCall ? findCaller(callObj) : RNull.instance; - RStringVector warningMessage = RDataFactory.createStringVectorFromScalar(formatMessage(msg, args)); - warningCallInvoke(call, warningMessage); - } - private static void warningCallInvoke(Object call, RStringVector warningMessage) { /* * Warnings generally do not prevent results being printed. However, this call into R will @@ -673,7 +667,7 @@ public class RErrorHandling { String fmsg = formatMessage(msg, args); String message = createWarningMessage(call, fmsg); if (w >= 2) { - throw RInternalError.unimplemented(); + throw errorcallDfltWithCall(null, call, RError.Message.CONVERTED_FROM_WARNING, fmsg); } else if (w == 1) { Utils.writeStderr(message, true); } else if (w == 0 && errorHandlingState.warnings.size() < errorHandlingState.maxWarnings) { 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 777d2404b541c7eda1faec1edb19336030babd47..00c3dc83014bedd5f116916b11069b7b3b847f64 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 @@ -42047,6 +42047,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 @@ -78159,6 +78199,14 @@ In f() : foo Warning message: In f() : foo +##com.oracle.truffle.r.test.builtins.TestBuiltin_warning.testwarning# +#op.warn <- getOption('warn'); options(warn = 2); f <- function() warning('foo'); f2 <- function() f(); tryCatch(f2(), finally={options(warn = op.warn)}) +Error in f() : (converted from warning) foo + +##com.oracle.truffle.r.test.builtins.TestBuiltin_warning.testwarning# +#op.warn <- getOption('warn'); options(warn = 2); f <- function() warning('foo'); tryCatch(f(), finally={options(warn = op.warn)}) +Error in f() : (converted from warning) foo + ##com.oracle.truffle.r.test.builtins.TestBuiltin_warning.testwarning# #options(warn=1); f <- function() warning('foo'); f() Warning in f() : foo 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 }"); + } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_warning.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_warning.java index bfdb68d4c6605342b937132948869c7d43c28705..a25c3a5a414bfea420a07ba1b53aeb903887d9cb 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_warning.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_warning.java @@ -4,7 +4,7 @@ * http://www.gnu.org/licenses/gpl-2.0.html * * Copyright (c) 2014, Purdue University - * Copyright (c) 2014, 2017, Oracle and/or its affiliates + * Copyright (c) 2014, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -25,5 +25,10 @@ public class TestBuiltin_warning extends TestBase { assertEval("options(warn=1); f <- function() warning('foo'); f()"); assertEval("f <- function() warning('foo'); f2 <- function() f(); f2()"); assertEval("options(warn=1); f <- function() warning('foo'); f2 <- function() f(); f2()"); + + // options(warn = 2) + assertEval("op.warn <- getOption('warn'); options(warn = 2); f <- function() warning('foo'); tryCatch(f(), finally={options(warn = op.warn)})"); + assertEval("op.warn <- getOption('warn'); options(warn = 2); f <- function() warning('foo'); f2 <- function() f(); tryCatch(f2(), finally={options(warn = op.warn)})"); } + }