diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index 61dc78f376e22a9f5c51367c0161864cd67eedb8..ec84baa9ed60d1161117164700bfa7e8d2c38e46 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -86,6 +86,7 @@ public final class REngine implements RContext.Engine { Locale.setDefault(Locale.ROOT); FastROptions.initialize(); Load_RFFIFactory.initialize(); + RAccuracyInfo.initialize(); singleton.crashOnFatalError = crashOnFatalErrorArg; singleton.builtinLookup = RBuiltinPackages.getInstance(); singleton.context = RContext.setRuntimeState(singleton, commandArgs, consoleHandler, new RASTHelperImpl(), headless); @@ -95,7 +96,6 @@ public final class REngine implements RContext.Engine { singleton.evalFunction = singleton.lookupBuiltin("eval"); RPackageVariables.initializeBase(); RVersionInfo.initialize(); - RAccuracyInfo.initialize(); RRNG.initialize(); TempDirPath.initialize(); LibPaths.initialize(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java index 875fc3e7b5c42e8c25c97c9d5ea0723c734e0378..b0aa685d8fcc4459e28aed0e32ae036b2448a73b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java @@ -41,7 +41,7 @@ public abstract class Abs extends RBuiltinNode { @Specialization protected RNull abs(RNull x) { controlVisibility(); - throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION); } @Specialization @@ -79,14 +79,14 @@ public abstract class Abs extends RBuiltinNode { @Specialization protected Object abs(RRaw vector) { controlVisibility(); - throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH); } @SuppressWarnings("unused") @Specialization protected Object abs(String vector) { controlVisibility(); - throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH); } @Specialization @@ -143,14 +143,14 @@ public abstract class Abs extends RBuiltinNode { @Specialization protected Object abs(RStringVector vector) { controlVisibility(); - throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH); } @SuppressWarnings("unused") @Specialization protected Object abs(RRawVector vector) { controlVisibility(); - throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH); } private int performInt(int value) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java index 2711a58673ceff2f0271114a98d7144e3db8f0f7..4f4f891f4fd685a2b110d829d5b910f419ccc618 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java @@ -90,7 +90,7 @@ public abstract class AsVector extends RBuiltinNode { private RSymbol castSymbol(VirtualFrame frame, Object operand) { if (castSymbol == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - castSymbol = insert(CastSymbolNodeFactory.create(null, false, false, false, false)); + castSymbol = insert(CastSymbolNodeFactory.create(null, false, false, false)); } return (RSymbol) castSymbol.executeSymbol(frame, operand); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseVariables.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseVariables.java index ae0cc149cbbc32f8b421ce5ba20aca3628303210..7fac75c41f6a7d35b16ebab1c68321b25d84b857 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseVariables.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseVariables.java @@ -40,7 +40,7 @@ import com.oracle.truffle.r.runtime.env.REnvironment.*; public class BaseVariables implements RPackageVariables.Handler { // @formatter:off private static final String[] VARS = new String[]{ - ".AutoloadEnv", ".BaseNamespaceEnv", ".GlobalEnv", ".Platform", ".Library", ".LibrarySite" + ".AutoloadEnv", ".BaseNamespaceEnv", ".GlobalEnv", ".Machine", ".Platform", ".Library", ".LibrarySite" }; // @formatter:on @@ -50,6 +50,7 @@ public class BaseVariables implements RPackageVariables.Handler { }; // @formatter:on + // @formatter:off private int initialized = -1; public BaseVariables() { @@ -77,6 +78,9 @@ public class BaseVariables implements RPackageVariables.Handler { String[] platformData = new String[]{"unix", File.separator, ".so", "unknown", "little", "source", File.pathSeparator, ""}; value = RDataFactory.createList(platformData, RDataFactory.createStringVector(PLATFORM_NAMES, RDataFactory.COMPLETE_VECTOR)); break; + case ".Machine": + value = createMachine(); + break; default: continue; } @@ -110,4 +114,39 @@ public class BaseVariables implements RPackageVariables.Handler { initialized++; } + private static final String[] MACHINE_NAMES = new String[] { + "double.eps", "double.neg.eps", "double.xmin", + "double.xmax", "double.base", "double.digits", + "double.rounding", "double.guard", "double.ulp.digits", + "double.neg.ulp.digits", "double.exponent", "double.min.exp", + "double.max.exp", "integer.max", "sizeof.long", + "sizeof.longlong", "sizeof.longdouble", "sizeof.pointer" + }; + // @formatter:on + + private static RList createMachine() { + Object[] values = new Object[MACHINE_NAMES.length]; + RAccuracyInfo acc = RAccuracyInfo.get(); + values[0] = acc.eps; + values[1] = acc.epsneg; + values[2] = acc.xmin; + values[3] = acc.xmax; + values[4] = acc.ibeta; + values[5] = acc.it; + values[6] = acc.irnd; + values[7] = acc.ngrd; + values[8] = acc.machep; + values[9] = acc.negep; + values[10] = acc.iexp; + values[11] = acc.minexp; + values[12] = acc.maxexp; + values[13] = Integer.MAX_VALUE; + // TODO platform specific + values[14] = 8; + values[15] = 8; + values[16] = 16; + values[17] = 8; + return RDataFactory.createList(values, RDataFactory.createStringVector(MACHINE_NAMES, RDataFactory.COMPLETE_VECTOR)); + } + } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java index 647df679a6a28b6465c42883ac1168a66a41c801..315f81fdbf428dce68d3fc49754eb13449df8736 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java @@ -51,52 +51,42 @@ public abstract class Cat extends RInvisibleBuiltinNode { @Child private ToStringNode toString; @CompilationFinal private String currentSep; + @CompilationFinal private boolean sepContainsNewline; private void ensureToString(String sep) { if (toString == null || !sep.equals(currentSep)) { CompilerDirectives.transferToInterpreterAndInvalidate(); - toString = insert(ToStringNodeFactory.create(null)); - toString.setSeparator(sep); - toString.setQuotes(false); - toString.setIntL(false); + toString = insert(ToStringNodeFactory.create(null, false, sep, false)); + sepContainsNewline = sep.contains("\n"); currentSep = sep; } } - @Specialization - protected Object cat(RNull arg, String file, String sep, byte fill, Object labels, byte append) { - controlVisibility(); - return RNull.instance; - } - @Specialization protected RNull cat(RMissing arg, String file, String sep, byte fill, Object labels, byte append) { controlVisibility(); return RNull.instance; } - @Specialization - protected RNull cat(VirtualFrame frame, RAbstractVector arg, String file, String sep, byte fill, Object labels, byte append) { - ensureToString(sep); - catIntl(toString.executeString(frame, arg)); - controlVisibility(); - return RNull.instance; - } - @Specialization(guards = "!isNull") protected RNull cat(VirtualFrame frame, RArgsValuesAndNames args, String file, String sep, byte fill, Object labels, byte append) { ensureToString(sep); Object[] argValues = args.getValues(); for (int i = 0; i < argValues.length; ++i) { + if (i > 0) { + catIntl(sep); + } catIntl(toString.executeString(frame, argValues[i])); - catSep(sep, argValues, i); + } + if (sepContainsNewline && argValues.length > 0) { + catIntl("\n"); } controlVisibility(); return RNull.instance; } @Specialization(guards = "isNull") - protected RNull catNull(VirtualFrame frame, RArgsValuesAndNames args, String file, String sep, byte fill, Object labels, byte append) { + protected RNull catNull(RArgsValuesAndNames args, String file, String sep, byte fill, Object labels, byte append) { controlVisibility(); return RNull.instance; } @@ -105,12 +95,6 @@ public abstract class Cat extends RInvisibleBuiltinNode { return args.length() == 1 && args.getValues()[0] == RNull.instance; } - private static void catSep(String sep, Object[] os, int j) { - if (j < os.length - 1 || sep.indexOf('\n') != -1) { - catIntl(sep); - } - } - @TruffleBoundary private static void catIntl(String s) { RContext.getInstance().getConsoleHandler().print(s); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java index ec77a35651f656b6db78b858a5eea222f0c02f7c..3a218a2792dfc50663e32b9ebcdf5f203f3d76a8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java @@ -40,6 +40,6 @@ public class Ceiling extends RWrapperBuiltinNode { @Override protected RNode createDelegate() { - return UnaryArithmeticNodeFactory.create(UnaryArithmetic.CEILING, this.getArguments()[0]); + return UnaryArithmeticNodeFactory.create(UnaryArithmetic.CEILING, RError.Message.NON_NUMERIC_MATH, getArguments()[0]); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Complex.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Complex.java index fb26e7b12c854f1a893ebab755bf1ef829c2276f..8aceec86d6c3aa3c53e912fac6563e13b6f87c31 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Complex.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Complex.java @@ -72,5 +72,4 @@ public abstract class Complex extends RBuiltinNode { protected static boolean zeroLength(int lengthOut, double real, double imaginary, int modulus, int argument) { return lengthOut == 0; } - } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java index ca5a98df978e07a5cbfb2019a7da2c16b8f8332d..7f25664c2d321c74a2738117da7ce1d6ec08f2b9 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java @@ -38,6 +38,7 @@ import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; +import com.oracle.truffle.r.runtime.ffi.*; public class FileFunctions { @@ -487,4 +488,51 @@ public class FileFunctions { return doXyzName(vec, basePathFunction); } } + + @RBuiltin(name = "dir.create", kind = INTERNAL, parameterNames = {"path", "showWarnings", "recursive", "mode"}) + public abstract static class DirCreate extends RInvisibleBuiltinNode { + @TruffleBoundary + @Specialization + protected byte dirCreate(RAbstractStringVector pathVec, byte showWarnings, byte recursive, RIntVector octMode) { + controlVisibility(); + boolean ok = true; + if (pathVec.getLength() != 1) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "path"); + } + String path = Utils.tildeExpand(pathVec.getDataAt(0)); + if (RRuntime.fromLogical(recursive)) { + ok = mkparentdirs(new File(path).getAbsoluteFile().getParentFile(), showWarnings, octMode.getDataAt(0)); + } + if (ok) { + ok = mkdir(path, showWarnings, octMode.getDataAt(0)); + } + return RRuntime.asLogical(ok); + } + + protected boolean mkparentdirs(File file, byte showWarnings, int mode) { + if (file.isDirectory()) { + return true; + } + if (file.exists()) { + return false; + } + if (mkparentdirs(file.getParentFile(), showWarnings, mode)) { + return mkdir(file.getAbsolutePath(), showWarnings, mode); + } else { + return false; + } + } + + protected boolean mkdir(String path, byte showWarnings, int mode) { + try { + RFFIFactory.getRFFI().getBaseRFFI().mkdir(path, mode); + return true; + } catch (IOException ex) { + if (RRuntime.fromLogical(showWarnings)) { + RContext.getInstance().setEvalWarning("cannot create dir '" + path + "'"); + } + return false; + } + } + } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java index dcb3e5e06de7c15f662abb650183f53953588739..a2ceda014336c1646bb1670fe22f44ebe70bbb17 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java @@ -40,6 +40,6 @@ public class Floor extends RWrapperBuiltinNode { @Override protected RNode createDelegate() { - return UnaryArithmeticNodeFactory.create(UnaryArithmetic.FLOOR, this.getArguments()[0]); + return UnaryArithmeticNodeFactory.create(UnaryArithmetic.FLOOR, RError.Message.NON_NUMERIC_MATH, getArguments()[0]); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java index 254cdf49e3e3f94bac724ae5e5224cc4c96f0677..5a00034f233844f4ed9ab24f93f42c6b8d02fc1b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java @@ -62,16 +62,35 @@ public abstract class Inherits extends RBuiltinNode { return which != RRuntime.LOGICAL_TRUE; } + @SuppressWarnings("unused") + public boolean whichFalse(RConnection x, RAbstractStringVector what, byte which) { + return which != RRuntime.LOGICAL_TRUE; + } + @Specialization(guards = "whichFalse") protected byte doInherits(VirtualFrame frame, RAbstractContainer x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) { return initInheritsNode().execute(frame, x, what); } + @Specialization(guards = "whichFalse") + protected byte doInherits(VirtualFrame frame, RConnection x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) { + return initInheritsNode().execute(frame, x, what); + } + + @Specialization(guards = "!whichFalse") + protected Object doesInherit(RAbstractVector x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) { + return doDoesInherit(x.getClassHierarchy(), what); + } + + @Specialization(guards = "!whichFalse") + protected Object doesInherit(RConnection x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) { + return doDoesInherit(x.getClassHierarchy(), what); + } + @TruffleBoundary // map operations lead to recursion resulting in compilation failure - @Specialization(guards = "!whichFalse") - protected Object doesInherit(RAbstractContainer x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) { - Map<String, Integer> classToPos = InheritsNode.initClassToPos(x); + private static Object doDoesInherit(RStringVector classHr, RAbstractStringVector what) { + Map<String, Integer> classToPos = InheritsNode.initClassToPos(classHr); int[] result = new int[what.getLength()]; for (int i = 0; i < what.getLength(); ++i) { final Integer pos = classToPos.get(what.getDataAt(i)); @@ -82,5 +101,6 @@ public abstract class Inherits extends RBuiltinNode { } } return RDataFactory.createIntVector(result, true); + } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java index 20a56e8623ebb1587d91643ae0367ab28c9e55a9..8f1d252a39f7a9d1f6d1eec7d3dcb17ef3e590bf 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java @@ -31,7 +31,6 @@ import com.oracle.truffle.r.nodes.*; import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; -import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java index efaaeb97aa534302257ee00b0c7ecdcd1482b076..637ca46292c4f347d9f0597bdf96f026635775f7 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java @@ -29,7 +29,6 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; -import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/character.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/character.R index b49ea5aac52f51310ba616bd1848d281f187c88b..c5f6904a3440d1f0b8a6956f7b10916dc888da9a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/character.R +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/character.R @@ -189,6 +189,6 @@ sQuote <- function(x) # paste0(before, x, after) #} # -#strtoi <- -# function(x, base = 0L) -# .Internal(strtoi(as.character(x), as.integer(base))) +strtoi <- + function(x, base = 0L) + .Internal(strtoi(as.character(x), as.integer(base))) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/octhex.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/octhex.R new file mode 100644 index 0000000000000000000000000000000000000000..bf4f3b8b14bcf485e19685f4d8957b7a0e5a4a15 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/octhex.R @@ -0,0 +1,127 @@ +# File src/library/base/R/octhex.R +# Part of the R package, http://www.R-project.org +# +# Copyright (C) 1995-2012 The R Core Team +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 for more details. +# +# A copy of the GNU General Public License is available at +# http://www.r-project.org/Licenses/ + +format.octmode <- function(x, width = NULL, ...) +{ + isna <- is.na(x) + y <- as.integer(x[!isna]) + fmt <- if(!is.null(width)) paste0("%0", width, "o") else "%o" + ans <- rep.int(NA_character_, length(x)) + ans0 <- sprintf(fmt, y) + if(is.null(width) && length(y) > 1L) { + ## previous version padded with zeroes to a common field width + nc <- max(nchar(ans0)) + ans0 <- sprintf(paste0("%0", nc, "o"), y) + } + ans[!isna] <- ans0 + dim(ans) <- dim(x) + dimnames(ans) <- dimnames(x) + names(ans) <- names(x) + ans +} + +as.character.octmode <- function(x, ...) format.octmode(x, ...) + +print.octmode <- function(x, ...) +{ + print(format(x), ...) + invisible(x) +} + +`[.octmode` <- function (x, i) +{ + cl <- oldClass(x) + y <- NextMethod("[") + oldClass(y) <- cl + y +} + +as.octmode <- function(x) +{ + if(inherits(x, "octmode")) return(x) + if(is.double(x) && x == as.integer(x)) x <- as.integer(x) + if(is.integer(x)) return(structure(x, class="octmode")) + if(is.character(x)) { + z <- strtoi(x, 8L) + if(!any(is.na(z) | z < 0)) return(structure(z, class="octmode")) + } + stop("'x' cannot be coerced to class \"octmode\"") +} + +## BioC packages cellHTS2 and flowCore misuse this for doubles, +## hence the as.integer() call +format.hexmode <- function(x, width = NULL, upper.case = FALSE, ...) +{ + isna <- is.na(x) + y <- as.integer(x[!isna]) + fmt0 <- if(upper.case) "X" else "x" + fmt <- if(!is.null(width)) paste0("%0", width, fmt0) else paste0("%", fmt0) + ans <- rep.int(NA_character_, length(x)) + ans0 <- sprintf(fmt, y) + if(is.null(width) && length(y) > 1L) { + ## previous version padded with zeroes to a common field width + nc <- max(nchar(ans0)) + ans0 <- sprintf(paste0("%0", nc, fmt0), y) + } + ans[!isna] <- ans0 + dim(ans) <- dim(x) + dimnames(ans) <- dimnames(x) + names(ans) <- names(x) + ans +} + +as.character.hexmode <- function(x, ...) format.hexmode(x, ...) + +print.hexmode <- function(x, ...) +{ + print(format(x), ...) + invisible(x) +} + +`[.hexmode` <- function (x, i) +{ + cl <- oldClass(x) + y <- NextMethod("[") + oldClass(y) <- cl + y +} + +as.hexmode <- function(x) +{ + if(inherits(x, "hexmode")) return(x) + if(is.double(x) && (x == as.integer(x))) x <- as.integer(x) + if(is.integer(x)) return(structure(x, class = "hexmode")) + if(is.character(x)) { + z <- strtoi(x, 16L) + if(!any(is.na(z) | z < 0)) return(structure(z, class = "hexmode")) + } + stop("'x' cannot be coerced to class \"hexmode\"") +} + + +`!.octmode` <- function(a) as.octmode(bitwNot(as.octmode(a))) + +`&.octmode` <- function(a, b) as.octmode(bitwAnd(as.octmode(a), as.octmode(b))) +`|.octmode` <- function(a, b) as.octmode(bitwOr(as.octmode(a), as.octmode(b))) +xor.octmode <- function(a, b) as.octmode(bitwXor(as.octmode(a), as.octmode(b))) + +`!.hexmode` <- function(a) as.hexmode(bitwNot(as.hexmode(a))) + +`&.hexmode` <- function(a, b) as.hexmode(bitwAnd(as.hexmode(a), as.hexmode(b))) +`|.hexmode` <- function(a, b) as.hexmode(bitwOr(as.hexmode(a), as.hexmode(b))) +xor.hexmode <- function(a, b) as.hexmode(bitwXor(as.hexmode(a), as.hexmode(b))) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java index 1e71255970ca752ae45fe1f56ffc88a53e27e0d3..f4271c3513fcc153107bfb3918dfdd8c2d85dbab 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java @@ -53,6 +53,7 @@ public class SortFunctions { // TODO Implement in R public abstract static class SortList extends RBuiltinNode { private final ConditionProfile orderProfile = ConditionProfile.createBinaryProfile(); + @Override public RNode[] getParameterValues() { return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RNull.instance), ConstantNode.create(RRuntime.LOGICAL_TRUE), ConstantNode.create(RRuntime.LOGICAL_FALSE), diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java new file mode 100644 index 0000000000000000000000000000000000000000..968f323d7cb2f34e0e36318408029478a5a3aacb --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014, 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.base; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.r.runtime.*; +import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; +import com.oracle.truffle.r.runtime.ffi.*; + +@RBuiltin(name = "strtoi", kind = RBuiltinKind.INTERNAL, parameterNames = {"x", "base"}) +public abstract class Strtoi extends RBuiltinNode { + @TruffleBoundary + @Specialization + protected RIntVector doStrtoi(RAbstractStringVector vec, int baseArg) { + int base = baseArg; + int[] data = new int[vec.getLength()]; + boolean complete = RDataFactory.COMPLETE_VECTOR; + for (int i = 0; i < data.length; i++) { + int dataValue = RRuntime.INT_NA; + try { + String s = vec.getDataAt(i); + if (s.length() == 0) { + complete = RDataFactory.INCOMPLETE_VECTOR; + } else { + if (base == 0) { + char ch0 = s.charAt(0); + if (ch0 == '0') { + if (s.length() > 1 && (s.charAt(1) == 'x' || s.charAt(1) == 'X')) { + base = 16; + } else { + base = 8; + } + } else { + base = 10; + } + } + long value = RFFIFactory.getRFFI().getBaseRFFI().strtol(s, base); + if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) { + complete = RDataFactory.INCOMPLETE_VECTOR; + } else { + dataValue = (int) value; + } + } + } catch (IllegalArgumentException ex) { + complete = RDataFactory.INCOMPLETE_VECTOR; + } + data[i] = dataValue; + } + return RDataFactory.createIntVector(data, complete); + } + +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java index a86cc41c076bb2d8b3d2560e9848cce0b913b807..3496b68623a38ad5c7cc75c9a61f6036fbb5281e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java @@ -27,6 +27,7 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import java.util.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.r.nodes.*; import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; @@ -38,6 +39,8 @@ import com.oracle.truffle.r.runtime.data.model.*; @RBuiltin(name = "vector", kind = INTERNAL, parameterNames = {"mode", "length"}) public abstract class Vector extends RBuiltinNode { + private final ValueProfile modeProfile = ValueProfile.createIdentityProfile(); + @Override public RNode[] getParameterValues() { // mode = "logical", length = 0 @@ -54,7 +57,7 @@ public abstract class Vector extends RBuiltinNode { @Specialization protected RAbstractVector vector(String mode, int length) { controlVisibility(); - switch (mode) { + switch (modeProfile.profile(mode)) { case "character": return RDataFactory.createStringVector(length); case "logical": @@ -72,5 +75,4 @@ public abstract class Vector extends RBuiltinNode { throw RError.error(getEncapsulatingSourceSection(), RError.Message.CANNOT_MAKE_VECTOR_OF_MODE, mode); } } - } 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 e2ad8848392a05547be2cc6afc3acba416997dc3..3b2e1647c639918a561c3c1d97aafa85331bdc0f 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 @@ -73,7 +73,7 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode { throw RError.error(getSourceSection(), RError.Message.ARGUMENT_EMPTY, 2); } else { CompilerDirectives.transferToInterpreterAndInvalidate(); - unaryNode = insert(UnaryArithmeticNodeFactory.create(unaryFactory, null)); + unaryNode = insert(UnaryArithmeticNodeFactory.create(unaryFactory, RError.Message.INVALID_ARG_TYPE_UNARY, null)); } } return unaryNode; 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 bf0e12563d7c088c68f28c7fd7a8de400fb30a9a..1e38b21933e742c4b75757cc2657a260e4b2e44b 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 @@ -22,10 +22,12 @@ */ package com.oracle.truffle.r.nodes.unary; +import java.util.function.*; + import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException; +import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; @@ -34,6 +36,7 @@ import com.oracle.truffle.r.runtime.ops.na.*; public abstract class CastComplexNode extends CastNode { private final NACheck naCheck = NACheck.create(); + private final BranchProfile warningBranch = BranchProfile.create(); public abstract Object executeComplex(VirtualFrame frame, int o); @@ -81,149 +84,54 @@ public abstract class CastComplexNode extends CastNode { naCheck.enable(operand); RComplex result = naCheck.convertStringToComplex(operand); if (RRuntime.isNA(result)) { + warningBranch.enter(); RError.warning(RError.Message.NA_INTRODUCED_COERCION); } return result; } - private double[] dataFromLogical(RLogicalVector operand) { - naCheck.enable(operand); - double[] ddata = new double[operand.getLength() << 1]; - for (int i = 0; i < operand.getLength(); i++) { - byte value = operand.getDataAt(i); - RComplex complexValue = naCheck.convertLogicalToComplex(value); - int index = i << 1; - ddata[index] = complexValue.getRealPart(); - ddata[index + 1] = complexValue.getImaginaryPart(); - } - return ddata; - } - - private double[] dataFromString(RStringVector operand) { + private RComplexVector createResultVector(RAbstractVector operand, IntFunction<RComplex> elementFunction) { naCheck.enable(operand); double[] ddata = new double[operand.getLength() << 1]; for (int i = 0; i < operand.getLength(); i++) { - String value = operand.getDataAt(i); - RComplex complexValue = naCheck.convertStringToComplex(value); - if (RRuntime.isNA(complexValue)) { - RError.warning(RError.Message.NA_INTRODUCED_COERCION); - } + RComplex complexValue = elementFunction.apply(i); int index = i << 1; ddata[index] = complexValue.getRealPart(); ddata[index + 1] = complexValue.getImaginaryPart(); } - return ddata; - } - - private static double[] dataFromRaw(RRawVector operand) { - double[] ddata = new double[operand.getLength() << 1]; - for (int i = 0; i < operand.getLength(); i++) { - byte value = operand.getDataAt(i).getValue(); - int index = i << 1; - ddata[index] = value; - ddata[index + 1] = 0; - } - return ddata; - } - - @Specialization - protected RComplexVector doIntVector(RIntVector operand) { - return performAbstractIntVector(operand); - } - - @Specialization - protected RComplexVector doIntSequence(RIntSequence operand) { - return performAbstractIntVector(operand); - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RComplexVector doLogicalVectorDims(RLogicalVector operand) { - double[] ddata = dataFromLogical(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RComplexVector doLogicalVectorNames(RLogicalVector operand) { - double[] ddata = dataFromLogical(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RComplexVector doLogicalVectorDimsNames(RLogicalVector operand) { - double[] ddata = dataFromLogical(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RComplexVector doLogicalVector(RLogicalVector operand) { - double[] ddata = dataFromLogical(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RComplexVector doStringVectorDims(RStringVector operand) { - double[] ddata = dataFromString(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RComplexVector doStringVectorNames(RStringVector operand) { - double[] ddata = dataFromString(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getNames()); + RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null); if (isAttrPreservation()) { ret.copyRegAttributesFrom(operand); } return ret; } - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RComplexVector doStringVectorDimsNames(RStringVector operand) { - double[] ddata = dataFromString(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; + @Specialization + protected RComplexVector doIntVector(RAbstractIntVector operand) { + return createResultVector(operand, index -> naCheck.convertIntToComplex(operand.getDataAt(index))); } - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RComplexVector doStringVector(RStringVector operand) { - double[] ddata = dataFromString(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; + @Specialization + protected RComplexVector doDoubleVector(RAbstractDoubleVector operand) { + return createResultVector(operand, index -> naCheck.convertDoubleToComplex(operand.getDataAt(index))); } @Specialization - protected RComplexVector doDoubleVector(RDoubleVector operand) { - return performAbstractDoubleVector(operand); + protected RComplexVector doLogicalVector(RLogicalVector operand) { + return createResultVector(operand, index -> naCheck.convertLogicalToComplex(operand.getDataAt(index))); } @Specialization - protected RComplexVector doDoubleSequence(RDoubleSequence operand) { - return performAbstractDoubleVector(operand); + protected RComplexVector doStringVector(RStringVector operand) { + return createResultVector(operand, index -> { + String value = operand.getDataAt(index); + RComplex complexValue = naCheck.convertStringToComplex(value); + if (RRuntime.isNA(complexValue)) { + warningBranch.enter(); + RError.warning(RError.Message.NA_INTRODUCED_COERCION); + } + return complexValue; + }); } @Specialization @@ -231,44 +139,9 @@ public abstract class CastComplexNode extends CastNode { return vector; } - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RComplexVector doRawVectorDims(RRawVector operand) { - double[] ddata = dataFromRaw(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, RDataFactory.COMPLETE_VECTOR, operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RComplexVector doRawVectorNames(RRawVector operand) { - double[] ddata = dataFromRaw(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, RDataFactory.COMPLETE_VECTOR, operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RComplexVector doRawVectorDimsNames(RRawVector operand) { - double[] ddata = dataFromRaw(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, RDataFactory.COMPLETE_VECTOR, operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) + @Specialization protected RComplexVector doRawVector(RRawVector operand) { - double[] ddata = dataFromRaw(operand); - RComplexVector ret = RDataFactory.createComplexVector(ddata, RDataFactory.COMPLETE_VECTOR); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; + return createResultVector(operand, index -> RDataFactory.createComplex(operand.getDataAt(index).getValue(), 0)); } @Fallback @@ -276,57 +149,4 @@ public abstract class CastComplexNode extends CastNode { public int doOther(Object operand) { throw new ConversionFailedException(operand.getClass().getName()); } - - private RComplexVector performAbstractIntVector(RAbstractIntVector operand) { - naCheck.enable(operand); - double[] ddata = new double[operand.getLength() << 1]; - for (int i = 0; i < operand.getLength(); i++) { - int value = operand.getDataAt(i); - RComplex complexValue = naCheck.convertIntToComplex(value); - int index = i << 1; - ddata[index] = complexValue.getRealPart(); - ddata[index + 1] = complexValue.getImaginaryPart(); - } - RComplexVector ret; - if (preserveDimensions() && preserveNames()) { - ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - } else if (preserveDimensions()) { - ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions()); - } else if (preserveNames()) { - ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getNames()); - } else { - ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA()); - } - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - private RComplexVector performAbstractDoubleVector(RAbstractDoubleVector operand) { - naCheck.enable(operand); - double[] ddata = new double[operand.getLength() << 1]; - for (int i = 0; i < operand.getLength(); i++) { - double value = operand.getDataAt(i); - RComplex complexValue = naCheck.convertDoubleToComplex(value); - int index = i << 1; - ddata[index] = complexValue.getRealPart(); - ddata[index + 1] = complexValue.getImaginaryPart(); - } - RComplexVector ret; - if (preserveDimensions() && preserveNames()) { - ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - } else if (preserveDimensions()) { - ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions()); - } else if (preserveNames()) { - ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getNames()); - } else { - ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA()); - } - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java index dec31f20a779fb164d1cb33468436064988a13fb..525d98a651664f5edac5003bcd4df612a07c7cc5 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java @@ -22,11 +22,13 @@ */ package com.oracle.truffle.r.nodes.unary; +import java.util.function.*; + import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException; +import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; @@ -35,6 +37,7 @@ import com.oracle.truffle.r.runtime.ops.na.*; public abstract class CastDoubleNode extends CastNode { private final NACheck naCheck = NACheck.create(); + private final BranchProfile warningBranch = BranchProfile.create(); public abstract Object executeDouble(VirtualFrame frame, int o); @@ -49,7 +52,7 @@ public abstract class CastDoubleNode extends CastNode { private Object castDoubleRecursive(VirtualFrame frame, Object o) { if (recursiveCastDouble == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - recursiveCastDouble = insert(CastDoubleNodeFactory.create(null, isNamesPreservation(), isDimensionsPreservation(), isAttrPreservation())); + recursiveCastDouble = insert(CastDoubleNodeFactory.create(null, isPreserveNames(), isDimensionsPreservation(), isAttrPreservation())); } return recursiveCastDouble.executeDouble(frame, o); } @@ -75,6 +78,7 @@ public abstract class CastDoubleNode extends CastNode { naCheck.enable(operand); double result = naCheck.convertComplexToDouble(operand); if (operand.getImaginaryPart() != 0.0) { + warningBranch.enter(); RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION); } return result; @@ -91,6 +95,7 @@ public abstract class CastDoubleNode extends CastNode { naCheck.enable(operand); double result = naCheck.convertStringToDouble(operand); if (isNA(result)) { + warningBranch.enter(); RError.warning(RError.Message.NA_INTRODUCED_COERCION); } return result; @@ -101,17 +106,35 @@ public abstract class CastDoubleNode extends CastNode { return RRuntime.raw2double(operand); } - private double[] dataFromLogical(RLogicalVector operand) { + private RDoubleVector createResultVector(RAbstractVector operand, double[] ddata) { + RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null); + if (isAttrPreservation()) { + ret.copyRegAttributesFrom(operand); + } + return ret; + } + + private RDoubleVector createResultVector(RAbstractVector operand, IntToDoubleFunction elementFunction) { naCheck.enable(operand); double[] ddata = new double[operand.getLength()]; for (int i = 0; i < operand.getLength(); i++) { - byte value = operand.getDataAt(i); - ddata[i] = naCheck.convertLogicalToDouble(value); + ddata[i] = elementFunction.applyAsDouble(i); } - return ddata; + return createResultVector(operand, ddata); } - private double[] dataFromString(RStringVector operand) { + @Specialization + protected RDoubleVector doIntVector(RAbstractIntVector operand) { + return createResultVector(operand, index -> naCheck.convertIntToDouble(operand.getDataAt(index))); + } + + @Specialization + protected RDoubleVector doLogicalVectorDims(RLogicalVector operand) { + return createResultVector(operand, index -> naCheck.convertLogicalToDouble(operand.getDataAt(index))); + } + + @Specialization + protected RDoubleVector doStringVector(RStringVector operand) { naCheck.enable(operand); double[] ddata = new double[operand.getLength()]; boolean warning = false; @@ -123,21 +146,14 @@ public abstract class CastDoubleNode extends CastNode { } } if (warning) { + warningBranch.enter(); RError.warning(RError.Message.NA_INTRODUCED_COERCION); } - return ddata; - } - - private static double[] dataFromRaw(RRawVector operand) { - double[] ddata = new double[operand.getLength()]; - for (int i = 0; i < operand.getLength(); i++) { - RRaw value = operand.getDataAt(i); - ddata[i] = RRuntime.raw2double(value); - } - return ddata; + return createResultVector(operand, ddata); } - private double[] dataFromComplex(RComplexVector operand) { + @Specialization + protected RDoubleVector doComplexVector(RComplexVector operand) { naCheck.enable(operand); double[] ddata = new double[operand.getLength()]; boolean warning = false; @@ -149,179 +165,15 @@ public abstract class CastDoubleNode extends CastNode { } } if (warning) { + warningBranch.enter(); RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION); } - return ddata; - } - - @Specialization - protected RDoubleVector doIntVector(RIntVector operand) { - return performAbstractIntVector(operand); + return createResultVector(operand, ddata); } @Specialization - protected RDoubleVector doIntVector(RIntSequence operand) { - return performAbstractIntVector(operand); - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RDoubleVector doLogicalVectorDims(RLogicalVector operand) { - double[] ddata = dataFromLogical(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RDoubleVector doLogicalVectorNames(RLogicalVector operand) { - double[] ddata = dataFromLogical(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RDoubleVector doLogicalVectorDimsNames(RLogicalVector operand) { - double[] ddata = dataFromLogical(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RDoubleVector doLogicalVector(RLogicalVector operand) { - double[] ddata = dataFromLogical(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RDoubleVector doStringVectorDims(RStringVector operand) { - double[] ddata = dataFromString(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RDoubleVector doStringVectorNames(RStringVector operand) { - double[] ddata = dataFromString(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RDoubleVector doStringVectorDimsNames(RStringVector operand) { - double[] ddata = dataFromString(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RDoubleVector doStringVector(RStringVector operand) { - double[] ddata = dataFromString(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RDoubleVector doComplexVectorDims(RComplexVector operand) { - double[] ddata = dataFromComplex(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RDoubleVector doComplexVectorNames(RComplexVector operand) { - double[] ddata = dataFromComplex(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RDoubleVector doComplexVectorDimsNames(RComplexVector operand) { - double[] ddata = dataFromComplex(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RDoubleVector doComplexVector(RComplexVector operand) { - double[] ddata = dataFromComplex(operand); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RDoubleVector doRawVectorDims(RRawVector vector) { - double[] ddata = dataFromRaw(vector); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), vector.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RDoubleVector doRawVectorNames(RRawVector vector) { - double[] ddata = dataFromRaw(vector); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RDoubleVector doRawVectorDimsNames(RRawVector vector) { - double[] ddata = dataFromRaw(vector); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), vector.getDimensions(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RDoubleVector doRawVector(RRawVector vector) { - double[] ddata = dataFromRaw(vector); - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; + protected RDoubleVector doRawVector(RRawVector operand) { + return createResultVector(operand, index -> RRuntime.raw2double(operand.getDataAt(index))); } @Specialization @@ -353,10 +205,10 @@ public abstract class CastDoubleNode extends CastNode { } else if (doubleVector.getLength() == 0) { result[i] = RRuntime.DOUBLE_NA; } else { - throw cannotCoerceListError(); + throw throwCannotCoerceListError("numeric"); } } else { - throw cannotCoerceListError(); + throw throwCannotCoerceListError("numeric"); } } } @@ -367,36 +219,9 @@ public abstract class CastDoubleNode extends CastNode { return ret; } - private RError cannotCoerceListError() { - throw RError.error(this.getSourceSection(), RError.Message.LIST_COERCION, "numeric"); - } - @Fallback @TruffleBoundary public double doOther(Object operand) { throw new ConversionFailedException(operand.getClass().getName()); } - - private RDoubleVector performAbstractIntVector(RAbstractIntVector operand) { - naCheck.enable(operand); - double[] ddata = new double[operand.getLength()]; - for (int i = 0; i < operand.getLength(); i++) { - int value = operand.getDataAt(i); - ddata[i] = naCheck.convertIntToDouble(value); - } - RDoubleVector ret; - if (preserveDimensions() && preserveNames()) { - ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - } else if (preserveDimensions()) { - ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions()); - } else if (preserveNames()) { - ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames()); - } else { - ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA()); - } - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java index 998644035246af4fc4f2002ea1b8bcf71d97e135..3cdc934cb82a28e8b22095d2a00984fa0eb1464c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java @@ -23,17 +23,19 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.*; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException; +import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.*; public abstract class CastIntegerNode extends CastNode { - private final NACheck check = NACheck.create(); + private final NACheck naCheck = NACheck.create(); + private final BranchProfile warningBranch = BranchProfile.create(); public abstract Object executeInt(VirtualFrame frame, int o); @@ -48,7 +50,7 @@ public abstract class CastIntegerNode extends CastNode { private Object castIntegerRecursive(VirtualFrame frame, Object o) { if (recursiveCastInteger == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - recursiveCastInteger = insert(CastIntegerNodeFactory.create(null, isNamesPreservation(), isDimensionsPreservation(), isAttrPreservation())); + recursiveCastInteger = insert(CastIntegerNodeFactory.create(null, isPreserveNames(), isDimensionsPreservation(), isAttrPreservation())); } return recursiveCastInteger.executeInt(frame, o); } @@ -70,8 +72,8 @@ public abstract class CastIntegerNode extends CastNode { @Specialization protected int doDouble(double operand) { - check.enable(operand); - return check.convertDoubleToInt(operand); + naCheck.enable(operand); + return naCheck.convertDoubleToInt(operand); } @Specialization @@ -86,15 +88,16 @@ public abstract class CastIntegerNode extends CastNode { @Specialization protected RIntSequence doDoubleSequence(RDoubleSequence operand) { - check.enable(operand); - return RDataFactory.createIntSequence(check.convertDoubleToInt(operand.getStart()), check.convertDoubleToInt(operand.getStride()), operand.getLength()); + naCheck.enable(operand); + return RDataFactory.createIntSequence(naCheck.convertDoubleToInt(operand.getStart()), naCheck.convertDoubleToInt(operand.getStride()), operand.getLength()); } @Specialization protected int doComplex(RComplex operand) { - check.enable(operand); - int result = check.convertComplexToInt(operand); + naCheck.enable(operand); + int result = naCheck.convertComplexToInt(operand); if (operand.getImaginaryPart() != 0.0) { + warningBranch.enter(); RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION); } return result; @@ -102,9 +105,10 @@ public abstract class CastIntegerNode extends CastNode { @Specialization protected int doCharacter(String operand) { - check.enable(operand); - int result = check.convertStringToInt(operand); + naCheck.enable(operand); + int result = naCheck.convertStringToInt(operand); if (isNA(result)) { + warningBranch.enter(); RError.warning(RError.Message.NA_INTRODUCED_COERCION); } return result; @@ -112,8 +116,8 @@ public abstract class CastIntegerNode extends CastNode { @Specialization protected int doBoolean(byte operand) { - check.enable(operand); - return check.convertLogicalToInt(operand); + naCheck.enable(operand); + return naCheck.convertLogicalToInt(operand); } @Specialization @@ -121,262 +125,81 @@ public abstract class CastIntegerNode extends CastNode { return RRuntime.raw2int(operand); } - private int[] dataFromComplex(RComplexVector operand) { - check.enable(operand); + private RIntVector createResultVector(RAbstractVector operand, int[] idata) { + RIntVector ret = RDataFactory.createIntVector(idata, naCheck.neverSeenNA(), isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null); + if (isAttrPreservation()) { + ret.copyRegAttributesFrom(operand); + } + return ret; + } + + @FunctionalInterface + private interface IntToIntFunction { + int apply(int value); + } + + private RIntVector createResultVector(RAbstractVector operand, IntToIntFunction elementFunction) { + naCheck.enable(operand); + int[] idata = new int[operand.getLength()]; + for (int i = 0; i < operand.getLength(); i++) { + idata[i] = elementFunction.apply(i); + } + return createResultVector(operand, idata); + } + + @Specialization + protected RIntVector doComplexVector(RComplexVector operand) { + naCheck.enable(operand); int length = operand.getLength(); int[] idata = new int[length]; boolean warning = false; for (int i = 0; i < length; i++) { RComplex data = operand.getDataAt(i); - idata[i] = check.convertComplexToInt(data, false); + idata[i] = naCheck.convertComplexToInt(data, false); if (data.getImaginaryPart() != 0.0) { warning = true; } } if (warning) { + warningBranch.enter(); RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION); } - return idata; + return createResultVector(operand, idata); } - private int[] dataFromString(RStringVector operand) { - check.enable(operand); + @Specialization + protected RIntVector doStringVector(RStringVector operand) { + naCheck.enable(operand); int[] idata = new int[operand.getLength()]; boolean warning = false; for (int i = 0; i < operand.getLength(); i++) { String value = operand.getDataAt(i); - idata[i] = check.convertStringToInt(value); + idata[i] = naCheck.convertStringToInt(value); if (RRuntime.isNA(idata[i])) { warning = true; } } if (warning) { + warningBranch.enter(); RError.warning(RError.Message.NA_INTRODUCED_COERCION); } - return idata; - } - - private int[] dataFromLogical(RLogicalVector operand) { - check.enable(operand); - int[] idata = new int[operand.getLength()]; - for (int i = 0; i < operand.getLength(); i++) { - byte value = operand.getDataAt(i); - idata[i] = check.convertLogicalToInt(value); - } - return idata; - } - - private static int[] dataFromRaw(RRawVector operand) { - int[] idata = new int[operand.getLength()]; - for (int i = 0; i < operand.getLength(); i++) { - RRaw value = operand.getDataAt(i); - idata[i] = RRuntime.raw2int(value); - } - return idata; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RIntVector doComplexVectorDims(RComplexVector vector) { - int[] result = dataFromComplex(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RIntVector doComplexVectorNames(RComplexVector vector) { - int[] result = dataFromComplex(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RIntVector doComplexVectorDimsNames(RComplexVector vector) { - int[] result = dataFromComplex(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RIntVector doComplexVector(RComplexVector vector) { - int[] result = dataFromComplex(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RIntVector doStringVectorDims(RStringVector vector) { - int[] result = dataFromString(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RIntVector doStringVectorNames(RStringVector vector) { - int[] result = dataFromString(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RIntVector doStringVectorDimsNames(RStringVector vector) { - int[] result = dataFromString(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RIntVector doStringVector(RStringVector vector) { - int[] result = dataFromString(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RIntVector doLogicalVectorDims(RLogicalVector vector) { - int[] result = dataFromLogical(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RIntVector doLogicalVectorNames(RLogicalVector vector) { - int[] result = dataFromLogical(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RIntVector doLogicalVectorDimsNames(RLogicalVector vector) { - int[] result = dataFromLogical(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - public RIntVector doLogicalVector(RLogicalVector vector) { - int[] result = dataFromLogical(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RIntVector doDoubleVectorDims(RDoubleVector vector) { - check.enable(vector); - int[] result = check.convertDoubleVectorToIntData(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RIntVector doDoubleVectorNames(RDoubleVector vector) { - check.enable(vector); - int[] result = check.convertDoubleVectorToIntData(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RIntVector doDoubleVectorDimsNames(RDoubleVector vector) { - check.enable(vector); - int[] result = check.convertDoubleVectorToIntData(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RIntVector doDoubleVector(RDoubleVector vector) { - check.enable(vector); - int[] result = check.convertDoubleVectorToIntData(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RIntVector doRawVectorDims(RRawVector vector) { - int[] result = dataFromRaw(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; + return createResultVector(operand, idata); } - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RIntVector doRawVectorNames(RRawVector vector) { - int[] result = dataFromRaw(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; + @Specialization + public RIntVector doLogicalVector(RLogicalVector operand) { + return createResultVector(operand, index -> naCheck.convertLogicalToInt(operand.getDataAt(index))); } - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RIntVector doRawVectorDimsNames(RRawVector vector) { - int[] result = dataFromRaw(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; + @Specialization + protected RIntVector doDoubleVector(RDoubleVector operand) { + naCheck.enable(operand); + return createResultVector(operand, naCheck.convertDoubleVectorToIntData(operand)); } - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RIntVector doRawVector(RRawVector vector) { - int[] result = dataFromRaw(vector); - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; + @Specialization + protected RIntVector doRawVector(RRawVector operand) { + return createResultVector(operand, index -> RRuntime.raw2int(operand.getDataAt(index))); } @Specialization @@ -398,14 +221,14 @@ public abstract class CastIntegerNode extends CastNode { } else if (intVector.getLength() == 0) { result[i] = RRuntime.INT_NA; } else { - throw cannotCoerceListError(); + throw throwCannotCoerceListError("integer"); } } else { - throw cannotCoerceListError(); + throw throwCannotCoerceListError("integer"); } } } - RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA()); + RIntVector ret = RDataFactory.createIntVector(result, naCheck.neverSeenNA()); if (isAttrPreservation()) { ret.copyRegAttributesFrom(list); } @@ -417,14 +240,9 @@ public abstract class CastIntegerNode extends CastNode { return factor.getVector(); } - private RError cannotCoerceListError() { - throw RError.error(this.getSourceSection(), RError.Message.LIST_COERCION, "integer"); - } - @Fallback @TruffleBoundary public int doOther(Object operand) { throw new ConversionFailedException(operand.getClass().getName()); } - } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java index 84c5863e47bb5307e7532bfe9896f0bf915a6c55..1c0133786222e3e28da4182a5bb92b80e7237999 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java @@ -44,8 +44,7 @@ public abstract class CastListNode extends CastNode { } @Specialization - @SuppressWarnings("unused") - protected RList doNull(RNull operand) { + protected RList doNull(@SuppressWarnings("unused") RNull operand) { return RDataFactory.createList(); } @@ -65,16 +64,7 @@ public abstract class CastListNode extends CastNode { for (int i = 0; i < data.length; ++i) { data[i] = operand.getDataAtAsObject(i); } - RList ret; - if (preserveDimensions() && preserveNames()) { - ret = RDataFactory.createList(data, operand.getDimensions(), operand.getNames()); - } else if (preserveDimensions()) { - ret = RDataFactory.createList(data, operand.getDimensions()); - } else if (preserveNames()) { - ret = RDataFactory.createList(data, operand.getNames()); - } else { - ret = RDataFactory.createList(data); - } + RList ret = RDataFactory.createList(data, isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null); if (isAttrPreservation()) { ret.copyRegAttributesFrom(operand); } @@ -95,5 +85,4 @@ public abstract class CastListNode extends CastNode { protected RList doDataFrame(VirtualFrame frame, RDataFrame operand) { return castList(frame, operand.getVector()); } - } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java index 6cad5ade807b7b9ee86d99420740c7bb56762308..0a6857b8a718338e1c25ff723bde49040e66f110 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java @@ -26,7 +26,6 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.r.nodes.unary.ConvertNode.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; @@ -45,7 +44,7 @@ public abstract class CastLogicalNode extends CastNode { private Object castLogicalRecursive(VirtualFrame frame, Object o) { if (recursiveCastLogical == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - recursiveCastLogical = insert(CastLogicalNodeFactory.create(null, isNamesPreservation(), isDimensionsPreservation(), isAttrPreservation())); + recursiveCastLogical = insert(CastLogicalNodeFactory.create(null, isPreserveNames(), isDimensionsPreservation(), isAttrPreservation())); } return recursiveCastLogical.executeLogical(frame, o); } @@ -89,33 +88,22 @@ public abstract class CastLogicalNode extends CastNode { return RRuntime.raw2logical(operand); } - private byte[] dataFromString(RStringVector operand) { - naCheck.enable(operand); - byte[] ldata = new byte[operand.getLength()]; - for (int i = 0; i < operand.getLength(); i++) { - String value = operand.getDataAt(i); - ldata[i] = naCheck.convertStringToLogical(value); - } - return ldata; + @FunctionalInterface + private interface IntToByteFunction { + byte apply(int value); } - private byte[] dataFromComplex(RComplexVector operand) { + private RLogicalVector createResultVector(RAbstractVector operand, IntToByteFunction elementFunction) { naCheck.enable(operand); - byte[] ldata = new byte[operand.getLength()]; + byte[] bdata = new byte[operand.getLength()]; for (int i = 0; i < operand.getLength(); i++) { - RComplex value = operand.getDataAt(i); - ldata[i] = naCheck.convertComplexToLogical(value); + bdata[i] = elementFunction.apply(i); } - return ldata; - } - - private static byte[] dataFromRaw(RRawVector operand) { - byte[] ldata = new byte[operand.getLength()]; - for (int i = 0; i < operand.getLength(); i++) { - RRaw value = operand.getDataAt(i); - ldata[i] = RRuntime.raw2logical(value); + RLogicalVector ret = RDataFactory.createLogicalVector(bdata, naCheck.neverSeenNA(), isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null); + if (isAttrPreservation()) { + ret.copyRegAttributesFrom(operand); } - return ldata; + return ret; } @Specialization @@ -124,143 +112,28 @@ public abstract class CastLogicalNode extends CastNode { } @Specialization - protected RLogicalVector doIntVector(RIntVector operand) { - return performAbstractIntVector(operand); - } - - @Specialization - protected RLogicalVector doIntSequence(RIntSequence operand) { - return performAbstractIntVector(operand); + protected RLogicalVector doIntVector(RAbstractIntVector operand) { + return createResultVector(operand, index -> naCheck.convertIntToLogical(operand.getDataAt(index))); } @Specialization - protected RLogicalVector doDoubleVector(RDoubleVector operand) { - return performAbstractDoubleVector(operand); + protected RLogicalVector doDoubleVector(RAbstractDoubleVector operand) { + return createResultVector(operand, index -> naCheck.convertDoubleToLogical(operand.getDataAt(index))); } @Specialization - protected RLogicalVector doDoubleSequence(RDoubleSequence operand) { - return performAbstractDoubleVector(operand); - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RLogicalVector doStringVectorDims(RStringVector operand) { - byte[] ldata = dataFromString(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RLogicalVector doStringVectorNames(RStringVector operand) { - byte[] ldata = dataFromString(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RLogicalVector doStringVectorDimsNames(RStringVector operand) { - byte[] ldata = dataFromString(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) protected RLogicalVector doStringVector(RStringVector operand) { - byte[] ldata = dataFromString(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RLogicalVector doComplexVectorDims(RComplexVector operand) { - byte[] ldata = dataFromComplex(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RLogicalVector doComplexVectorNames(RComplexVector operand) { - byte[] ldata = dataFromComplex(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RLogicalVector doComplexVectorDimsNames(RComplexVector operand) { - byte[] ldata = dataFromComplex(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; + return createResultVector(operand, index -> naCheck.convertStringToLogical(operand.getDataAt(index))); } - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) + @Specialization protected RLogicalVector doComplexVector(RComplexVector operand) { - byte[] ldata = dataFromComplex(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; + return createResultVector(operand, index -> naCheck.convertComplexToLogical(operand.getDataAt(index))); } - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) + @Specialization protected RLogicalVector doRawVectorDims(RRawVector operand) { - byte[] ldata = dataFromRaw(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, RDataFactory.COMPLETE_VECTOR, operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RLogicalVector doRawVectorNames(RRawVector operand) { - byte[] ldata = dataFromRaw(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, RDataFactory.COMPLETE_VECTOR, operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RLogicalVector doRawVectorDimsNames(RRawVector operand) { - byte[] ldata = dataFromRaw(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, RDataFactory.COMPLETE_VECTOR, operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RLogicalVector doRawVector(RRawVector operand) { - byte[] ldata = dataFromRaw(operand); - RLogicalVector ret = RDataFactory.createLogicalVector(ldata, RDataFactory.COMPLETE_VECTOR); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; + return createResultVector(operand, index -> RRuntime.raw2logical(operand.getDataAt(index))); } @Specialization @@ -282,10 +155,10 @@ public abstract class CastLogicalNode extends CastNode { } else if (logicalVector.getLength() == 0) { result[i] = RRuntime.LOGICAL_NA; } else { - throw cannotCoerceListError(); + throw throwCannotCoerceListError("logical"); } } else { - throw cannotCoerceListError(); + throw throwCannotCoerceListError("logical"); } } } @@ -296,10 +169,6 @@ public abstract class CastLogicalNode extends CastNode { return ret; } - private RError cannotCoerceListError() { - throw RError.error(this.getSourceSection(), RError.Message.LIST_COERCION, "logical"); - } - @Specialization protected RArgsValuesAndNames doArgsValueAndNames(RArgsValuesAndNames values) { return values; @@ -315,50 +184,4 @@ public abstract class CastLogicalNode extends CastNode { public int doOther(Object operand) { throw new ConversionFailedException(operand.getClass().getName()); } - - private RLogicalVector performAbstractIntVector(RAbstractIntVector operand) { - naCheck.enable(operand); - byte[] ddata = new byte[operand.getLength()]; - for (int i = 0; i < operand.getLength(); i++) { - int value = operand.getDataAt(i); - ddata[i] = naCheck.convertIntToLogical(value); - } - RLogicalVector ret; - if (preserveDimensions() && preserveNames()) { - ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - } else if (preserveDimensions()) { - ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getDimensions()); - } else if (preserveNames()) { - ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getNames()); - } else { - ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA()); - } - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - private RLogicalVector performAbstractDoubleVector(RAbstractDoubleVector operand) { - naCheck.enable(operand); - byte[] ddata = new byte[operand.getLength()]; - for (int i = 0; i < operand.getLength(); i++) { - double value = operand.getDataAt(i); - ddata[i] = naCheck.convertDoubleToLogical(value); - } - RLogicalVector ret; - if (preserveDimensions() && preserveNames()) { - ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames()); - } else if (preserveDimensions()) { - ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getDimensions()); - } else if (preserveNames()) { - ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getNames()); - } else { - ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA()); - } - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastNode.java index 25ebaf0870b74a5aec7bf80d7443719dcd2aeded..b06e0110514929340b5c5058744a7d27eb5ca39c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastNode.java @@ -24,24 +24,28 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.utilities.*; +import com.oracle.truffle.r.runtime.*; -@NodeFields({@NodeField(name = "namesPreservation", type = boolean.class), @NodeField(name = "dimensionsPreservation", type = boolean.class), - @NodeField(name = "attrPreservation", type = boolean.class)}) +@NodeFields({@NodeField(name = "preserveNames", type = boolean.class), @NodeField(name = "dimensionsPreservation", type = boolean.class), @NodeField(name = "attrPreservation", type = boolean.class)}) public abstract class CastNode extends UnaryNode { + private final BranchProfile listCoercionErrorBranch = BranchProfile.create(); + public abstract Object executeCast(VirtualFrame frame, Object value); - protected abstract boolean isNamesPreservation(); + protected abstract boolean isPreserveNames(); protected abstract boolean isDimensionsPreservation(); protected abstract boolean isAttrPreservation(); - protected boolean preserveNames() { - return isNamesPreservation(); + protected boolean isPreserveDimensions() { + return isDimensionsPreservation(); } - protected boolean preserveDimensions() { - return isDimensionsPreservation(); + protected RError throwCannotCoerceListError(String type) { + listCoercionErrorBranch.enter(); + throw RError.error(getSourceSection(), RError.Message.LIST_COERCION, type); } } 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 1c9473026df1b76f091d55544a41f678b4674f7d..82b85b9192c6a318fe9e7c8902356fac0876ebf8 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 @@ -25,13 +25,15 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException; +import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; public abstract class CastRawNode extends CastNode { + private final BranchProfile warningBranch = BranchProfile.create(); + public abstract Object executeRaw(VirtualFrame frame, int o); public abstract Object executeRaw(VirtualFrame frame, double o); @@ -49,6 +51,7 @@ public abstract class CastRawNode extends CastNode { protected RRaw doInt(int operand) { int intResult = RRuntime.int2rawIntValue(operand); if (intResult != operand) { + warningBranch.enter(); RError.warning(RError.Message.OUT_OF_RANGE); } return RDataFactory.createRaw((byte) intResult); @@ -58,6 +61,7 @@ public abstract class CastRawNode extends CastNode { protected RRaw doDouble(double operand) { int intResult = RRuntime.double2rawIntValue(operand); if (intResult != (int) operand) { + warningBranch.enter(); RError.warning(RError.Message.OUT_OF_RANGE); } return RDataFactory.createRaw((byte) intResult); @@ -67,9 +71,11 @@ public abstract class CastRawNode extends CastNode { protected RRaw doComplex(RComplex operand) { int intResult = RRuntime.complex2rawIntValue(operand); if (operand.getImaginaryPart() != 0) { + warningBranch.enter(); RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION); } if (intResult != (int) operand.getRealPart()) { + warningBranch.enter(); RError.warning(RError.Message.OUT_OF_RANGE); } return RDataFactory.createRaw((byte) intResult); @@ -92,36 +98,42 @@ public abstract class CastRawNode extends CastNode { // need to cast to int to catch conversion warnings int intVal = RRuntime.string2int(operand); if (RRuntime.isNA(intVal)) { + warningBranch.enter(); RError.warning(RError.Message.NA_INTRODUCED_COERCION); } return doInt(intVal); } - private static byte[] dataFromComplex(RComplexVector operand) { - byte[] bdata = new byte[operand.getLength()]; - boolean imaginaryDiscardedWarning = false; - boolean outOfRangeWarning = false; - for (int i = 0; i < operand.getLength(); i++) { - RComplex complexVal = operand.getDataAt(i); - int intRawValue = RRuntime.complex2rawIntValue(complexVal); - if (complexVal.getImaginaryPart() != 0.0) { - imaginaryDiscardedWarning = true; - } - if ((int) complexVal.getRealPart() != intRawValue) { - outOfRangeWarning = true; + private RRawVector createResultVector(RAbstractVector operand, byte[] bdata) { + RRawVector ret = RDataFactory.createRawVector(bdata, isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null); + if (isAttrPreservation()) { + ret.copyRegAttributesFrom(operand); + } + return ret; + } + + @Specialization + protected RRawVector doIntVector(RAbstractIntVector operand) { + int length = operand.getLength(); + byte[] bdata = new byte[length]; + boolean warning = false; + for (int i = 0; i < length; ++i) { + int intValue = operand.getDataAt(i); + int intRawValue = RRuntime.int2rawIntValue(intValue); + if (intRawValue != intValue) { + warning = true; } bdata[i] = (byte) intRawValue; } - if (imaginaryDiscardedWarning) { - RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION); - } - if (outOfRangeWarning) { + if (warning) { + warningBranch.enter(); RError.warning(RError.Message.OUT_OF_RANGE); } - return bdata; + return createResultVector(operand, bdata); } - private static byte[] dataFromLogical(RLogicalVector operand) { + @Specialization + protected RRawVector doLogicalVector(RLogicalVector operand) { byte[] bdata = new byte[operand.getLength()]; boolean warning = false; for (int i = 0; i < operand.getLength(); i++) { @@ -133,12 +145,14 @@ public abstract class CastRawNode extends CastNode { bdata[i] = (byte) intRawValue; } if (warning) { + warningBranch.enter(); RError.warning(RError.Message.OUT_OF_RANGE); } - return bdata; + return createResultVector(operand, bdata); } - private static byte[] dataFromString(RStringVector operand) { + @Specialization + protected RRawVector doStringVector(RStringVector operand) { byte[] bdata = new byte[operand.getLength()]; boolean naCoercionWarning = false; boolean outOfRangeWarning = false; @@ -154,152 +168,61 @@ public abstract class CastRawNode extends CastNode { bdata[i] = (byte) intRawValue; } if (naCoercionWarning) { + warningBranch.enter(); RError.warning(RError.Message.NA_INTRODUCED_COERCION); } if (outOfRangeWarning) { + warningBranch.enter(); RError.warning(RError.Message.OUT_OF_RANGE); } - return bdata; + return createResultVector(operand, bdata); } @Specialization - protected RRawVector doIntVector(RIntVector value) { - return performAbstractIntVector(value); - } - - @Specialization - protected RRawVector doIntSequence(RIntSequence value) { - return performAbstractIntVector(value); - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RRawVector doLogicalVectorDims(RLogicalVector operand) { - byte[] bdata = dataFromLogical(operand); - RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RRawVector doLogicalVectorNames(RLogicalVector operand) { - byte[] bdata = dataFromLogical(operand); - RRawVector ret = RDataFactory.createRawVector(bdata, operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RRawVector doLogicalVectorDimsNames(RLogicalVector operand) { - byte[] bdata = dataFromLogical(operand); - RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RRawVector doLogicalVector(RLogicalVector operand) { - byte[] bdata = dataFromLogical(operand); - RRawVector ret = RDataFactory.createRawVector(bdata); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RRawVector doStringVectorDims(RStringVector operand) { - byte[] bdata = dataFromString(operand); - RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RRawVector doStringVectorNames(RStringVector operand) { - byte[] bdata = dataFromString(operand); - RRawVector ret = RDataFactory.createRawVector(bdata, operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RRawVector doStringVectorDimsNames(RStringVector operand) { - byte[] bdata = dataFromString(operand); - RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); - } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RRawVector doStringVector(RStringVector operand) { - byte[] bdata = dataFromString(operand); - RRawVector ret = RDataFactory.createRawVector(bdata); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); + protected RRawVector doComplexVector(RComplexVector operand) { + byte[] bdata = new byte[operand.getLength()]; + boolean imaginaryDiscardedWarning = false; + boolean outOfRangeWarning = false; + for (int i = 0; i < operand.getLength(); i++) { + RComplex complexVal = operand.getDataAt(i); + int intRawValue = RRuntime.complex2rawIntValue(complexVal); + if (complexVal.getImaginaryPart() != 0.0) { + imaginaryDiscardedWarning = true; + } + if ((int) complexVal.getRealPart() != intRawValue) { + outOfRangeWarning = true; + } + bdata[i] = (byte) intRawValue; } - return ret; - } - - @Specialization(guards = {"!preserveNames", "preserveDimensions"}) - protected RRawVector doRawVectorDims(RComplexVector operand) { - byte[] bdata = dataFromComplex(operand); - RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); + if (imaginaryDiscardedWarning) { + warningBranch.enter(); + RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION); } - return ret; - } - - @Specialization(guards = {"preserveNames", "!preserveDimensions"}) - protected RRawVector doComplexVectorNames(RComplexVector operand) { - byte[] bdata = dataFromComplex(operand); - RRawVector ret = RDataFactory.createRawVector(bdata, operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); + if (outOfRangeWarning) { + warningBranch.enter(); + RError.warning(RError.Message.OUT_OF_RANGE); } - return ret; + return createResultVector(operand, bdata); } - @Specialization(guards = {"preserveNames", "preserveDimensions"}) - protected RRawVector doComplexVectorDimsNames(RComplexVector operand) { - byte[] bdata = dataFromComplex(operand); - RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions(), operand.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); + @Specialization + protected RRawVector doDoubleVector(RAbstractDoubleVector operand) { + int length = operand.getLength(); + byte[] bdata = new byte[length]; + boolean warning = false; + for (int i = 0; i < length; ++i) { + double doubleValue = operand.getDataAt(i); + int intRawValue = RRuntime.double2rawIntValue(doubleValue); + if (intRawValue != (int) doubleValue) { + warning = true; + } + bdata[i] = (byte) intRawValue; } - return ret; - } - - @Specialization(guards = {"!preserveNames", "!preserveDimensions"}) - protected RRawVector doComplexVector(RComplexVector operand) { - byte[] bdata = dataFromComplex(operand); - RRawVector ret = RDataFactory.createRawVector(bdata); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(operand); + if (warning) { + warningBranch.enter(); + RError.warning(RError.Message.OUT_OF_RANGE); } - return ret; - } - - @Specialization - protected RRawVector doDoubleVector(RDoubleVector value) { - return performAbstractDoubleVector(value); - } - - @Specialization - protected RRawVector doDoubleSequence(RDoubleSequence value) { - return performAbstractDoubleVector(value); + return createResultVector(operand, bdata); } @Specialization @@ -312,66 +235,4 @@ public abstract class CastRawNode extends CastNode { public int doOther(Object operand) { throw new ConversionFailedException(operand.getClass().getName()); } - - private RRawVector performAbstractIntVector(RAbstractIntVector value) { - int length = value.getLength(); - byte[] array = new byte[length]; - boolean warning = false; - for (int i = 0; i < length; ++i) { - int intValue = value.getDataAt(i); - int intRawValue = RRuntime.int2rawIntValue(intValue); - if (intRawValue != intValue) { - warning = true; - } - array[i] = (byte) intRawValue; - } - if (warning) { - RError.warning(RError.Message.OUT_OF_RANGE); - } - RRawVector ret; - if (preserveDimensions() && preserveNames()) { - ret = RDataFactory.createRawVector(array, value.getDimensions(), value.getNames()); - } else if (preserveDimensions()) { - ret = RDataFactory.createRawVector(array, value.getDimensions()); - } else if (preserveNames()) { - ret = RDataFactory.createRawVector(array, value.getNames()); - } else { - ret = RDataFactory.createRawVector(array); - } - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(value); - } - return ret; - } - - private RRawVector performAbstractDoubleVector(RAbstractDoubleVector value) { - int length = value.getLength(); - byte[] array = new byte[length]; - boolean warning = false; - for (int i = 0; i < length; ++i) { - double doubleValue = value.getDataAt(i); - int intRawValue = RRuntime.double2rawIntValue(doubleValue); - if (intRawValue != (int) doubleValue) { - warning = true; - } - array[i] = (byte) intRawValue; - } - if (warning) { - RError.warning(RError.Message.OUT_OF_RANGE); - } - RRawVector ret; - if (preserveDimensions() && preserveNames()) { - ret = RDataFactory.createRawVector(array, value.getDimensions(), value.getNames()); - } else if (preserveDimensions()) { - ret = RDataFactory.createRawVector(array, value.getDimensions()); - } else if (preserveNames()) { - ret = RDataFactory.createRawVector(array, value.getNames()); - } else { - ret = RDataFactory.createRawVector(array); - } - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(value); - } - return ret; - } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java index 336a953cd8cae19d2b96c553afd127f9c94a7dde..4717be1f29d280a3beb9f5f8312abfa54ac99bbc 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java @@ -22,6 +22,8 @@ */ package com.oracle.truffle.r.nodes.unary; +import java.util.function.*; + import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.runtime.data.*; @@ -30,7 +32,7 @@ import com.oracle.truffle.r.runtime.data.model.*; @NodeField(name = "emptyVectorConvertedToNull", type = boolean.class) public abstract class CastStringNode extends CastNode { - @Child private ToStringNode toString = ToStringNodeFactory.create(null); + @Child private ToStringNode toString = ToStringNodeFactory.create(null, false, ToStringNode.DEFAULT_SEPARATOR, false); public abstract Object executeString(VirtualFrame frame, int o); @@ -42,10 +44,6 @@ public abstract class CastStringNode extends CastNode { public abstract boolean isEmptyVectorConvertedToNull(); - public CastStringNode() { - toString.setQuotes(false); - } - @Specialization protected RNull doNull(@SuppressWarnings("unused") RNull operand) { return RNull.instance; @@ -76,40 +74,16 @@ public abstract class CastStringNode extends CastNode { return toString.executeString(frame, value); } - private String[] dataFromLogical(VirtualFrame frame, RLogicalVector operand) { - String[] sdata = new String[operand.getLength()]; - for (int i = 0; i < operand.getLength(); i++) { - byte value = operand.getDataAt(i); - sdata[i] = toString.executeString(frame, value); - } - return sdata; - } - - private String[] dataFromComplex(VirtualFrame frame, RComplexVector operand) { + private RStringVector createResultVector(RAbstractVector operand, IntFunction<String> elementFunction) { String[] sdata = new String[operand.getLength()]; for (int i = 0; i < operand.getLength(); i++) { - RComplex value = operand.getDataAt(i); - sdata[i] = toString.executeString(frame, value); + sdata[i] = elementFunction.apply(i); } - return sdata; - } - - private String[] dataFromRaw(VirtualFrame frame, RRawVector operand) { - String[] sdata = new String[operand.getLength()]; - for (int i = 0; i < operand.getLength(); i++) { - RRaw value = operand.getDataAt(i); - sdata[i] = toString.executeString(frame, value); - } - return sdata; - } - - private String[] dataFromList(VirtualFrame frame, RList operand) { - String[] sdata = new String[operand.getLength()]; - for (int i = 0; i < operand.getLength(); i++) { - Object value = operand.getDataAt(i); - sdata[i] = toString.executeString(frame, value); + RStringVector ret = RDataFactory.createStringVector(sdata, RDataFactory.COMPLETE_VECTOR, isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null); + if (isAttrPreservation()) { + ret.copyRegAttributesFrom(operand); } - return sdata; + return ret; } @Specialization(guards = "isZeroLength") @@ -123,183 +97,33 @@ public abstract class CastStringNode extends CastNode { } @Specialization(guards = "!isZeroLength") - protected RStringVector doIntVector(VirtualFrame frame, RIntVector vector) { - return performAbstractIntVector(frame, vector); + protected RStringVector doIntVector(VirtualFrame frame, RAbstractIntVector operand) { + return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index))); } @Specialization(guards = "!isZeroLength") - protected RStringVector doDoubleVector(VirtualFrame frame, RDoubleVector vector) { - return performAbstractDoubleVector(frame, vector); + protected RStringVector doDoubleVector(VirtualFrame frame, RAbstractDoubleVector operand) { + return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index))); } @Specialization(guards = "!isZeroLength") - protected RStringVector doIntSequence(VirtualFrame frame, RIntSequence vector) { - return performAbstractIntVector(frame, vector); + protected RStringVector doLogicalVector(VirtualFrame frame, RLogicalVector operand) { + return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index))); } @Specialization(guards = "!isZeroLength") - protected RStringVector doDoubleSequence(VirtualFrame frame, RDoubleSequence vector) { - return performAbstractDoubleVector(frame, vector); - } - - @Specialization(guards = {"!isZeroLength", "!preserveNames", "preserveDimensions"}) - protected RStringVector doLogicalVectorDims(VirtualFrame frame, RLogicalVector vector) { - String[] result = dataFromLogical(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "preserveNames", "!preserveDimensions"}) - protected RStringVector doLogicalVectorNames(VirtualFrame frame, RLogicalVector vector) { - String[] result = dataFromLogical(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "preserveNames", "preserveDimensions"}) - protected RStringVector doLogicalVectorDimsNames(VirtualFrame frame, RLogicalVector vector) { - String[] result = dataFromLogical(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "!preserveNames", "!preserveDimensions"}) - protected RStringVector doLogicalVector(VirtualFrame frame, RLogicalVector vector) { - String[] result = dataFromLogical(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "!preserveNames", "preserveDimensions"}) - protected RStringVector doComplexVectorDims(VirtualFrame frame, RComplexVector vector) { - String[] result = dataFromComplex(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "preserveNames", "!preserveDimensions"}) - protected RStringVector doComplexVectorNames(VirtualFrame frame, RComplexVector vector) { - String[] result = dataFromComplex(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "preserveNames", "preserveDimensions"}) - protected RStringVector doComplexVectorDimsNames(VirtualFrame frame, RComplexVector vector) { - String[] result = dataFromComplex(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "!preserveNames", "!preserveDimensions"}) - protected RStringVector doComplexVector(VirtualFrame frame, RComplexVector vector) { - String[] result = dataFromComplex(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "!preserveNames", "preserveDimensions"}) - protected RStringVector doRawVectorDims(VirtualFrame frame, RRawVector vector) { - String[] result = dataFromRaw(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "preserveNames", "!preserveDimensions"}) - protected RStringVector doRawVectorNames(VirtualFrame frame, RRawVector vector) { - String[] result = dataFromRaw(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "preserveNames", "preserveDimensions"}) - protected RStringVector doRawVectorDimsNames(VirtualFrame frame, RRawVector vector) { - String[] result = dataFromRaw(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions(), vector.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "!preserveNames", "!preserveDimensions"}) - protected RStringVector doRawVector(VirtualFrame frame, RRawVector vector) { - String[] result = dataFromRaw(frame, vector); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "!preserveNames", "preserveDimensions"}) - protected RStringVector doListDims(VirtualFrame frame, RList list) { - String[] result = dataFromList(frame, list); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, list.getDimensions()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(list); - } - return ret; + protected RStringVector doComplexVector(VirtualFrame frame, RComplexVector operand) { + return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index))); } - @Specialization(guards = {"!isZeroLength", "preserveNames", "!preserveDimensions"}) - protected RStringVector doListNames(VirtualFrame frame, RList list) { - String[] result = dataFromList(frame, list); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, list.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(list); - } - return ret; - } - - @Specialization(guards = {"!isZeroLength", "preserveNames", "preserveDimensions"}) - protected RStringVector doListDimsNames(VirtualFrame frame, RList list) { - String[] result = dataFromList(frame, list); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, list.getDimensions(), list.getNames()); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(list); - } - return ret; + @Specialization(guards = "!isZeroLength") + protected RStringVector doRawVector(VirtualFrame frame, RRawVector operand) { + return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index))); } - @Specialization(guards = {"!isZeroLength", "!preserveNames", "!preserveDimensions"}) - protected RStringVector doList(VirtualFrame frame, RList list) { - String[] result = dataFromList(frame, list); - RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR); - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(list); - } - return ret; + @Specialization(guards = "!isZeroLength") + protected RStringVector doList(VirtualFrame frame, RList operand) { + return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index))); } @Specialization @@ -307,50 +131,7 @@ public abstract class CastStringNode extends CastNode { return s.getName(); } - private RStringVector performAbstractIntVector(VirtualFrame frame, RAbstractIntVector vector) { - int length = vector.getLength(); - String[] result = new String[length]; - for (int i = 0; i < length; i++) { - result[i] = toString.executeString(frame, vector.getDataAt(i)); - } - RStringVector ret; - if (preserveDimensions()) { - ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions()); - } else if (preserveNames()) { - ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames()); - } else { - ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR); - } - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - - private RStringVector performAbstractDoubleVector(VirtualFrame frame, RAbstractDoubleVector vector) { - int length = vector.getLength(); - String[] result = new String[length]; - for (int i = 0; i < length; i++) { - result[i] = toString.executeString(frame, vector.getDataAt(i)); - } - RStringVector ret; - if (preserveDimensions() && preserveNames()) { - ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions(), vector.getNames()); - } else if (preserveDimensions()) { - ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions()); - } else if (preserveNames()) { - ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames()); - } else { - ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR); - } - if (isAttrPreservation()) { - ret.copyRegAttributesFrom(vector); - } - return ret; - } - protected boolean isZeroLength(RAbstractVector vector) { return vector.getLength() == 0; } - } 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 a259c8413429806b16a27468ac972b4f13617d4b..e85dc40662ae128ec3eb11a52e7955bdc114c287 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 @@ -28,15 +28,14 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@NodeField(name = "emptyVectorConvertedToNull", type = boolean.class) public abstract class CastSymbolNode extends CastNode { - @Child private ToStringNode toString = ToStringNodeFactory.create(null); + + @Child private ToStringNode toString = ToStringNodeFactory.create(null, true, ToStringNode.DEFAULT_SEPARATOR, false); public abstract Object executeSymbol(VirtualFrame frame, Object o); - @SuppressWarnings("unused") @Specialization - protected RSymbol doNull(RNull value) { + protected RSymbol doNull(@SuppressWarnings("unused") RNull value) { throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_TYPE_LENGTH, "symbol", 0); } @@ -61,7 +60,7 @@ public abstract class CastSymbolNode extends CastNode { } @Specialization - protected RSymbol doStringVector(@SuppressWarnings("unused") VirtualFrame frame, RStringVector value) { + protected RSymbol doStringVector(RStringVector value) { // Only element 0 interpreted return doString(value.getDataAt(0)); } @@ -85,5 +84,4 @@ public abstract class CastSymbolNode extends CastNode { private static RSymbol backQuote(String s) { return RDataFactory.createSymbol("`" + s + "`"); } - } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java index bd1ff7d31e5f95fe2a70b0f86c65db87362e1ac8..5b03886ca5b28b2c524d194c7b2934a84730775c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java @@ -58,8 +58,7 @@ public abstract class CastToContainerNode extends CastNode { } @Specialization(guards = "!preserveNonContainer") - @SuppressWarnings("unused") - protected RAbstractVector cast(RFunction f) { + protected RAbstractVector cast(@SuppressWarnings("unused") RFunction f) { return RDataFactory.createList(); } @@ -87,5 +86,4 @@ public abstract class CastToContainerNode extends CastNode { protected RPairList cast(RPairList pairlist) { return pairlist; } - } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java index 1265f614724f7df9d285e3cdb5aa146771ca0327..ef73dffc189cf3f2fa66b96298bb4ba9c00c5cef 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java @@ -39,14 +39,12 @@ public abstract class CastToVectorNode extends CastNode { } @Specialization(guards = "preserveNonVector") - @SuppressWarnings("unused") - protected RNull castNull(RNull rnull) { + protected RNull castNull(@SuppressWarnings("unused") RNull rnull) { return RNull.instance; } @Specialization(guards = "!preserveNonVector") - @SuppressWarnings("unused") - protected RAbstractVector cast(RNull rnull) { + protected RAbstractVector cast(@SuppressWarnings("unused") RNull rnull) { return RDataFactory.createList(); } @@ -56,8 +54,7 @@ public abstract class CastToVectorNode extends CastNode { } @Specialization(guards = "!preserveNonVector") - @SuppressWarnings("unused") - protected RAbstractVector cast(RFunction f) { + protected RAbstractVector cast(@SuppressWarnings("unused") RFunction f) { return RDataFactory.createList(); } @@ -65,5 +62,4 @@ public abstract class CastToVectorNode extends CastNode { protected RAbstractVector cast(RAbstractVector vector) { return vector; } - } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConversionFailedException.java similarity index 74% rename from com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertNode.java rename to com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConversionFailedException.java index b2467a7ae8d4fcaa581ab8fa6ae7f9fe90cf92b7..f73ca2e54dd03b88da7da8963c379adb98eb61bf 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConversionFailedException.java @@ -22,17 +22,12 @@ */ package com.oracle.truffle.r.nodes.unary; -public abstract class ConvertNode extends UnaryNode { +/** Thrown by a convert node. Indicates that a parent node must rewrite itself. */ +public final class ConversionFailedException extends RuntimeException { - /** Thrown by a convert node. Indicates that a parent node must rewrite itself. */ - public static final class ConversionFailedException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public ConversionFailedException(String message) { - super(message); - } + private static final long serialVersionUID = 1L; + public ConversionFailedException(String message) { + super(message); } - } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java index 62752158abcdedcd75b8b2f736a31f29e8f29b2b..bfb6bbe3f0cdd36fd158bc73bc064e00ad6d6de9 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java @@ -33,7 +33,9 @@ import com.oracle.truffle.r.runtime.ops.na.*; public abstract class ConvertBooleanNode extends UnaryNode { - private final NACheck check = NACheck.create(); + private final NAProfile naProfile = NAProfile.create(); + private final BranchProfile invalidElementCountBranch = BranchProfile.create(); + private final BranchProfile errorBranch = BranchProfile.create(); @Override public abstract byte executeByte(VirtualFrame frame); @@ -41,47 +43,41 @@ public abstract class ConvertBooleanNode extends UnaryNode { public abstract byte executeByte(VirtualFrame frame, Object operandValue); @Specialization - protected byte doLogical(byte value) { - check.enable(value); - if (check.check(value)) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.NA_UNEXP); + protected byte doInt(int value) { + if (naProfile.isNA(value)) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL); } - return value; + return RRuntime.int2logicalNoCheck(value); } @Specialization - protected byte doInt(int value) { - check.enable(value); - if (check.check(value)) { + protected byte doDouble(double value) { + if (naProfile.isNA(value)) { throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL); } - return RRuntime.asLogical(value != 0); + return RRuntime.double2logicalNoCheck(value); } @Specialization - protected byte doDouble(double value) { - check.enable(value); - if (check.check(value)) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL); + protected byte doLogical(byte value) { + if (naProfile.isNA(value)) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NA_UNEXP); } - return RRuntime.asLogical(value != 0D); + return value; } @Specialization protected byte doComplex(RComplex value) { - check.enable(value); - if (check.check(value)) { + if (naProfile.isNA(value)) { throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL); } - return RRuntime.asLogical(!value.isZero()); + return RRuntime.complex2logicalNoCheck(value); } @Specialization protected byte doString(String value) { - check.enable(value); - byte logicalValue = check.convertStringToLogical(value); - check.enable(logicalValue); - if (check.check(logicalValue)) { + byte logicalValue = RRuntime.string2logicalNoCheck(value); + if (naProfile.isNA(logicalValue)) { throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL); } return logicalValue; @@ -89,113 +85,55 @@ public abstract class ConvertBooleanNode extends UnaryNode { @Specialization protected byte doRaw(RRaw value) { - return RRuntime.asLogical(value.getValue() != 0); + return RRuntime.raw2logical(value); } - @Specialization - protected byte doIntSequence(RIntSequence value) { - if (value.getLength() > 1) { - moreThanOneElem.enter(); - RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1); + private void checkLength(RAbstractVector value) { + if (value.getLength() != 1) { + invalidElementCountBranch.enter(); + if (value.getLength() == 0) { + errorBranch.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.LENGTH_ZERO); + } else { + RError.warning(getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1); + } } - return RRuntime.asLogical(value.getStart() != 0); } @Specialization - protected byte doDoubleSequence(RDoubleSequence value) { - if (value.getLength() > 1) { - moreThanOneElem.enter(); - RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1); - } - return RRuntime.asLogical(value.getStart() != 0D); - } - - @SuppressWarnings("unused") - @Specialization(guards = "isEmpty") - protected byte doEmptyVector(RAbstractVector value) { - throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_ZERO); + protected byte doIntVector(RAbstractIntVector value) { + checkLength(value); + return doInt(value.getDataAt(0)); } - private final BranchProfile moreThanOneElem = BranchProfile.create(); - - @Specialization(guards = "!isEmpty") - protected byte doIntVector(RIntVector value) { - if (value.getLength() > 1) { - moreThanOneElem.enter(); - RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1); - } - check.enable(value); - if (check.check(value.getDataAt(0))) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL); - } - return RRuntime.asLogical(value.getDataAt(0) != 0); - } - - @Specialization(guards = "!isEmpty") - protected byte doDoubleVector(RDoubleVector value) { - if (value.getLength() > 1) { - moreThanOneElem.enter(); - RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1); - } - check.enable(value); - if (check.check(value.getDataAt(0))) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL); - } - return RRuntime.asLogical(value.getDataAt(0) != 0D); + @Specialization + protected byte doDoubleVector(RAbstractDoubleVector value) { + checkLength(value); + return doDouble(value.getDataAt(0)); } - @Specialization(guards = "!isEmpty") + @Specialization protected byte doLogicalVector(RLogicalVector value) { - if (value.getLength() > 1) { - moreThanOneElem.enter(); - RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1); - } - check.enable(value); - if (check.check(value.getDataAt(0))) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.NA_UNEXP); - } - return RRuntime.asLogical(value.getDataAt(0) != RRuntime.LOGICAL_FALSE); + checkLength(value); + return doLogical(value.getDataAt(0)); } - @Specialization(guards = "!isEmpty") + @Specialization protected byte doComplexVector(RComplexVector value) { - if (value.getLength() > 1) { - moreThanOneElem.enter(); - RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1); - } - check.enable(value); - if (check.check(value.getDataAt(0))) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL); - } - return RRuntime.asLogical(!value.getDataAt(0).isZero()); + checkLength(value); + return doComplex(value.getDataAt(0)); } - @Specialization(guards = "!isEmpty") - protected byte doRawVector(RRawVector value) { - if (value.getLength() > 1) { - moreThanOneElem.enter(); - RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1); - } - return RRuntime.asLogical(value.getDataAt(0).getValue() != 0); - } - - @Specialization(guards = "!isEmpty") + @Specialization protected byte doStringVector(RStringVector value) { - if (value.getLength() > 1) { - moreThanOneElem.enter(); - RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1); - } - check.enable(value); - byte logicalValue = check.convertStringToLogical(value.getDataAt(0)); - check.enable(logicalValue); - if (check.check(logicalValue)) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL); - } - return logicalValue; + checkLength(value); + return doString(value.getDataAt(0)); } - protected boolean isEmpty(RAbstractVector vector) { - return vector.getLength() == 0; + @Specialization + protected byte doRawVector(RRawVector value) { + checkLength(value); + return doRaw(value.getDataAt(0)); } public static ConvertBooleanNode create(RNode node) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertInt.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertInt.java index 23120f161e24efd8692edf5d6fd748353c311d09..87f054d849e832b191626e2955788b845ee07e5d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertInt.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertInt.java @@ -25,17 +25,10 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException; import com.oracle.truffle.r.runtime.*; -//@PolymorphicLimit(1) public abstract class ConvertInt extends UnaryNode { - @Override - public abstract int executeInteger(VirtualFrame frame); - - public abstract Object execute(VirtualFrame frame, Object operand); - public abstract int executeInteger(VirtualFrame frame, Object operand); @Specialization diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertIntExact.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertIntExact.java deleted file mode 100644 index 3bacef7794b80d3adc5f7b3d0bee56699c7e46d4..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertIntExact.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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.unary; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.data.*; - -//@PolymorphicLimit(1) -public abstract class ConvertIntExact extends UnaryNode { - - public abstract Object execute(VirtualFrame frame, Object operand); - - public abstract int executeInteger(VirtualFrame frame, Object operand); - - @Specialization - protected int doInt(int operand) { - return operand; - } - - @Specialization - protected int doLogical(byte operand) { - return RRuntime.logical2int(operand); - } - - @Specialization - protected double doInt(RIntVector operand) { - if (operand.getLength() == 1) { - return operand.getDataAt(0); - } else { - throw fail(operand.getClass().getName()); - } - } - - @Fallback - public int doOther(Object operand) { - throw fail(operand.getClass().getName()); - } - - @TruffleBoundary - private static ConversionFailedException fail(String className) { - throw new ConversionFailedException(className); - } - -} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java index 15c0e4ee65ec6fab870ede16cdc3f5cd2923ff3a..6c00b5e208f2c403a5b5755f93f7e8a4d818a653 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java @@ -16,6 +16,7 @@ import java.util.*; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.r.nodes.binary.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; @@ -26,6 +27,9 @@ import com.oracle.truffle.r.runtime.env.*; * Basic support for "inherits" that is used by the {@code inherits} builtin and others. */ public abstract class InheritsNode extends BinaryNode { + + private final ConditionProfile sizeOneProfile = ConditionProfile.createBinaryProfile(); + public abstract byte execute(VirtualFrame frame, Object x, Object what); @SuppressWarnings("unused") @@ -40,27 +44,43 @@ public abstract class InheritsNode extends BinaryNode { return RRuntime.LOGICAL_FALSE; } - // map operations lead to recursion resulting in compilation failure @Specialization protected Object doesInherit(RAbstractContainer x, RAbstractStringVector what) { - Map<String, Integer> classToPos = initClassToPos(x); - for (int i = 0; i < what.getLength(); ++i) { - if (classToPos.get(what.getDataAt(i)) != null) { - return RRuntime.LOGICAL_TRUE; + return checkDoesInherit(x.getClassHierarchy(), what); + } + + @Specialization + protected Object doesInherit(RConnection x, RAbstractStringVector what) { + return checkDoesInherit(x.getClassHierarchy(), what); + } + + private byte checkDoesInherit(RStringVector classHr, RAbstractStringVector what) { + if (sizeOneProfile.profile(what.getLength() == 1)) { + String whatString = what.getDataAt(0); + for (int i = 0; i < classHr.getLength(); ++i) { + if (whatString.equals(classHr.getDataAt(i))) { + return RRuntime.LOGICAL_TRUE; + } + } + } else { + Map<String, Integer> classToPos = initClassToPos(classHr); + for (int i = 0; i < what.getLength(); ++i) { + if (classToPos.get(what.getDataAt(i)) != null) { + return RRuntime.LOGICAL_TRUE; + } } } return RRuntime.LOGICAL_FALSE; } + // map operations lead to recursion resulting in compilation failure @TruffleBoundary - public static Map<String, Integer> initClassToPos(RAbstractContainer x) { - RStringVector klass = x.getClassHierarchy(); - + public static HashMap<String, Integer> initClassToPos(RStringVector classHr) { // Create a mapping for elements to their respective positions // in the vector for faster lookup. - Map<String, Integer> classToPos = new HashMap<>(); - for (int i = 0; i < klass.getLength(); ++i) { - classToPos.put(klass.getDataAt(i), i); + HashMap<String, Integer> classToPos = new HashMap<>(); + for (int i = 0; i < classHr.getLength(); ++i) { + classToPos.put(classHr.getDataAt(i), i); } return classToPos; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java index 8d6f00e2784395b844f6698d6812c2afd0768775..87adc3278cafbb79c4be9c13f13a20f083ef35c8 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java @@ -22,6 +22,8 @@ */ package com.oracle.truffle.r.nodes.unary; +import java.util.function.*; + import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -29,25 +31,27 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.env.*; +@NodeFields({@NodeField(name = "quotes", type = boolean.class), @NodeField(name = "separator", type = String.class), @NodeField(name = "appendIntL", type = boolean.class)}) public abstract class ToStringNode extends UnaryNode { + public static final String DEFAULT_SEPARATOR = ", "; + @Child private ToStringNode recursiveToString; + @CompilationFinal private Boolean separatorContainsNewlineCache; - @CompilationFinal private boolean quotes = true; + protected abstract boolean isQuotes(); - @CompilationFinal private String separator; + protected abstract String getSeparator(); - @CompilationFinal private boolean intL = false; + protected abstract boolean isAppendIntL(); private String toStringRecursive(VirtualFrame frame, Object o) { if (recursiveToString == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - recursiveToString = insert(ToStringNodeFactory.create(null)); - recursiveToString.setSeparator(separator); - recursiveToString.setQuotes(quotes); - recursiveToString.setIntL(intL); + recursiveToString = insert(ToStringNodeFactory.create(null, isQuotes(), getSeparator(), isAppendIntL())); } return recursiveToString.executeString(frame, o); } @@ -55,26 +59,6 @@ public abstract class ToStringNode extends UnaryNode { // FIXME custom separators require breaking some rules // FIXME separator should be a @NodeField - not possible as default values cannot be set - public ToStringNode() { - this.separator = DEFAULT_SEPARATOR; - } - - public ToStringNode(ToStringNode prev) { - this.separator = prev.separator; - this.quotes = prev.quotes; - this.intL = prev.intL; - } - - public static final String DEFAULT_SEPARATOR = ", "; - - public final void setSeparator(String separator) { - this.separator = separator; - } - - public final void setIntL(boolean intL) { - this.intL = intL; - } - @Override public abstract String execute(VirtualFrame frame); @@ -87,7 +71,7 @@ public abstract class ToStringNode extends UnaryNode { if (RRuntime.isNA(value)) { return value; } - if (quotes) { + if (isQuotes()) { return RRuntime.quoteString(value); } return value; @@ -116,7 +100,7 @@ public abstract class ToStringNode extends UnaryNode { @Specialization protected String toString(int operand) { - return RRuntime.intToString(operand, intL); + return RRuntime.intToString(operand, isAppendIntL()); } @Specialization @@ -130,132 +114,68 @@ public abstract class ToStringNode extends UnaryNode { } @TruffleBoundary - @Specialization - protected String toString(RIntVector vector) { + private String createResultForVector(RAbstractVector vector, String empty, IntFunction<String> elementFunction) { int length = vector.getLength(); if (length == 0) { - return "integer(0)"; + return empty; } StringBuilder b = new StringBuilder(); for (int i = 0; i < length; i++) { - b.append(toString(vector.getDataAt(i))); - if (i < length - 1) { - b.append(separator); + if (i > 0) { + b.append(getSeparator()); } + b.append(elementFunction.apply(i)); } return RRuntime.toString(b); } + @Specialization + protected String toString(RIntVector vector) { + return createResultForVector(vector, "integer(0)", index -> toString(vector.getDataAt(index))); + } + @TruffleBoundary @Specialization protected String toString(RDoubleVector vector) { - int length = vector.getLength(); - if (length == 0) { - return "numeric(0)"; - } - StringBuilder b = new StringBuilder(); - for (int i = 0; i < length; i++) { - b.append(toString(vector.getDataAt(i))); - if (i < length - 1) { - b.append(separator); - } - } - return RRuntime.toString(b); + return createResultForVector(vector, "numeric(0)", index -> toString(vector.getDataAt(index))); } @TruffleBoundary @Specialization protected String toString(RStringVector vector) { - int length = vector.getLength(); - if (length == 0) { - return "character(0)"; - } - StringBuilder b = new StringBuilder(); - for (int i = 0; i < length; ++i) { - b.append(toString(vector.getDataAt(i))); - if (i < length - 1) { - b.append(separator); - } - } - return RRuntime.toString(b); + return createResultForVector(vector, "character(0)", index -> toString(vector.getDataAt(index))); } - @TruffleBoundary @Specialization protected String toString(RLogicalVector vector) { - int length = vector.getLength(); - if (length == 0) { - return "logical(0)"; - } - StringBuilder b = new StringBuilder(); - for (int i = 0; i < length; ++i) { - b.append(toString(vector.getDataAt(i))); - if (i < length - 1) { - b.append(separator); - } - } - return RRuntime.toString(b); + return createResultForVector(vector, "logical(0)", index -> toString(vector.getDataAt(index))); } - @TruffleBoundary @Specialization protected String toString(RRawVector vector) { - int length = vector.getLength(); - if (length == 0) { - return "raw(0)"; - } - StringBuilder b = new StringBuilder(); - for (int i = 0; i < length; ++i) { - b.append(toString(vector.getDataAt(i))); - if (i < length - 1) { - b.append(separator); - } - } - return RRuntime.toString(b); + return createResultForVector(vector, "raw(0)", index -> toString(vector.getDataAt(index))); } - @TruffleBoundary @Specialization protected String toString(RComplexVector vector) { - int length = vector.getLength(); - if (length == 0) { - return "complex(0)"; - } - StringBuilder b = new StringBuilder(); - for (int i = 0; i < length; ++i) { - b.append(toString(vector.getDataAt(i))); - if (i < length - 1) { - b.append(separator); - } - } - return RRuntime.toString(b); + return createResultForVector(vector, "complex(0)", index -> toString(vector.getDataAt(index))); } - @TruffleBoundary @Specialization protected String toString(VirtualFrame frame, RList vector) { - int length = vector.getLength(); - if (length == 0) { - return "list()"; - } - StringBuilder b = new StringBuilder(); - for (int i = 0; i < length; ++i) { - Object value = vector.getDataAt(i); + return createResultForVector(vector, "list()", index -> { + Object value = vector.getDataAt(index); if (value instanceof RList) { RList l = (RList) value; if (l.getLength() == 0) { - b.append("list()"); + return "list()"; } else { - b.append("list(").append(toStringRecursive(frame, l)).append(')'); + return "list(" + toStringRecursive(frame, l) + ')'; } } else { - b.append(toStringRecursive(frame, value)); - } - if (i < length - 1) { - b.append(separator); + return toStringRecursive(frame, value); } - } - return RRuntime.toString(b); + }); } @Specialization @@ -272,8 +192,4 @@ public abstract class ToStringNode extends UnaryNode { protected String toString(REnvironment env) { return env.toString(); } - - public void setQuotes(boolean quotes) { - this.quotes = quotes; - } } 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 3ef99e4131fb6d7aa9c5df4ae4ca313d7c4f9e39..71ba384bec71689ff9039d84ef8f03ddc292ab51 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,6 +26,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.runtime.*; +import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.closures.*; import com.oracle.truffle.r.runtime.data.model.*; @@ -36,56 +37,41 @@ public abstract class UnaryArithmeticNode extends UnaryNode { private final UnaryArithmetic arithmetic; + private final NAProfile naProfile = NAProfile.create(); private final NACheck na = NACheck.create(); - public UnaryArithmeticNode(UnaryArithmeticFactory factory) { + private final Message error; + + public UnaryArithmeticNode(UnaryArithmeticFactory factory, Message error) { this.arithmetic = factory.create(); + this.error = error; } public UnaryArithmeticNode(UnaryArithmeticNode prev) { this.arithmetic = prev.arithmetic; + this.error = prev.error; } public abstract Object execute(VirtualFrame frame, Object operand); - @Specialization(guards = "!isNA") + @Specialization protected int doInt(int operand) { - return arithmetic.op(operand); + return naProfile.isNA(operand) ? RRuntime.INT_NA : arithmetic.op(operand); } - @Specialization(guards = "isNA") - protected int doIntNA(@SuppressWarnings("unused") int operand) { - return RRuntime.INT_NA; - } - - @Specialization(guards = "!isNA") + @Specialization protected double doDouble(double operand) { - return arithmetic.op(operand); + return naProfile.isNA(operand) ? RRuntime.DOUBLE_NA : arithmetic.op(operand); } - @Specialization(guards = "isNA") - protected double doDoubleNA(@SuppressWarnings("unused") double operand) { - return RRuntime.DOUBLE_NA; - } - - @Specialization(guards = "!isNA") + @Specialization protected RComplex doComplex(RComplex operand) { - return arithmetic.op(operand.getRealPart(), operand.getImaginaryPart()); + return naProfile.isNA(operand) ? RRuntime.createComplexNA() : arithmetic.op(operand.getRealPart(), operand.getImaginaryPart()); } - @Specialization(guards = "isNA") - protected RComplex doComplexNA(@SuppressWarnings("unused") RComplex operand) { - return RRuntime.createComplexNA(); - } - - @Specialization(guards = "!isNA") + @Specialization protected int doLogical(byte operand) { - return arithmetic.op(operand); - } - - @Specialization(guards = "isNA") - protected int doLogicalNA(@SuppressWarnings("unused") byte operand) { - return RRuntime.INT_NA; + return naProfile.isNA(operand) ? RRuntime.INT_NA : arithmetic.op(operand); } @TruffleBoundary @@ -188,14 +174,9 @@ public abstract class UnaryArithmeticNode extends UnaryNode { return doIntVectorNA(RClosures.createLogicalToIntVector(operands, na)); } - @Specialization - protected Object doStringVector(@SuppressWarnings("unused") RAbstractStringVector operands) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE_UNARY); - } - - @Specialization - protected Object doRawVector(@SuppressWarnings("unused") RAbstractRawVector operands) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE_UNARY); + @Fallback + protected Object invalidArgType(@SuppressWarnings("unused") Object operand) { + throw RError.error(getEncapsulatingSourceSection(), error); } protected static boolean isComplete(RAbstractVector cv) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java index 2dc3bcdb4b82a23374457bf0bdaa717f6d26c198..bc46cceb0891e71932cfdcde91384bc64e36663b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java @@ -73,33 +73,32 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode { return semantics.isNullInt(); } - @SuppressWarnings("unused") - @Specialization(guards = "isNullInt") - protected int doInt(RNull operand, byte naRm) { + private void emptyWarning() { if (semantics.getEmptyWarning() != null) { RError.warning(semantics.emptyWarning); } + } + + @SuppressWarnings("unused") + @Specialization(guards = "isNullInt") + protected int doInt(RNull operand, byte naRm) { + emptyWarning(); return semantics.getIntStart(); } @SuppressWarnings("unused") @Specialization(guards = "!isNullInt") protected double doDouble(RNull operand, byte naRm) { - if (semantics.getEmptyWarning() != null) { - RError.warning(semantics.emptyWarning); - } + emptyWarning(); return semantics.getDoubleStart(); } @Specialization protected int doInt(int operand, byte naRm) { - boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE); na.enable(operand); - if (profiledNaRm) { + if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) { if (na.check(operand)) { - if (semantics.getEmptyWarning() != null) { - RError.warning(semantics.emptyWarning); - } + emptyWarning(); return semantics.getIntStart(); } else { return operand; @@ -111,13 +110,10 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode { @Specialization protected double doDouble(double operand, byte naRm) { - boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE); na.enable(operand); - if (profiledNaRm) { + if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) { if (na.check(operand)) { - if (semantics.getEmptyWarning() != null) { - RError.warning(semantics.emptyWarning); - } + emptyWarning(); return semantics.getIntStart(); } else { return operand; @@ -129,13 +125,10 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode { @Specialization protected int doLogical(byte operand, byte naRm) { - boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE); na.enable(operand); - if (profiledNaRm) { + if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) { if (na.check(operand)) { - if (semantics.getEmptyWarning() != null) { - RError.warning(semantics.emptyWarning); - } + emptyWarning(); return semantics.getIntStart(); } else { return operand; @@ -148,13 +141,10 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode { @Specialization protected RComplex doComplex(RComplex operand, byte naRm) { if (semantics.supportComplex) { - boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE); na.enable(operand); - if (profiledNaRm) { + if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) { if (na.check(operand)) { - if (semantics.getEmptyWarning() != null) { - RError.warning(semantics.emptyWarning); - } + emptyWarning(); return RRuntime.double2complex(semantics.getDoubleStart()); } else { return operand; @@ -170,13 +160,10 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode { @Specialization protected String doString(String operand, byte naRm) { if (semantics.supportString) { - boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE); na.enable(operand); - if (profiledNaRm) { + if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) { if (na.check(operand)) { - if (semantics.getEmptyWarning() != null) { - RError.warning(semantics.emptyWarning); - } + emptyWarning(); return semantics.getStringStart(); } else { return operand; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java index 12bd94521df0e9df296403bb4f5e3570b78df6ed..48dec55dff2ed08ad05db19b061cea0f087582d3 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java @@ -23,6 +23,7 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; @@ -33,156 +34,140 @@ import com.oracle.truffle.r.runtime.ops.na.*; public abstract class UnaryNotNode extends RBuiltinNode { private final NACheck na = NACheck.create(); + private final NAProfile naProfile = NAProfile.create(); + private final ConditionProfile zeroLengthProfile = ConditionProfile.createBinaryProfile(); - @Specialization - protected byte doLogical(byte operand) { - na.enable(operand); - if (na.check(operand)) { - return RRuntime.LOGICAL_NA; - } - return not(operand); + private static byte not(byte value) { + return (value == RRuntime.LOGICAL_TRUE ? RRuntime.LOGICAL_FALSE : RRuntime.LOGICAL_TRUE); } - @Specialization - protected byte doInt(int operand) { - na.enable(operand); - if (na.check(operand)) { - return RRuntime.LOGICAL_NA; - } + private static byte not(int operand) { return RRuntime.asLogical(operand == 0); } - @Specialization - protected byte doDouble(double operand) { - na.enable(operand); - if (na.check(operand)) { - return RRuntime.LOGICAL_NA; - } + private static byte not(double operand) { return RRuntime.asLogical(operand == 0); } - @Specialization - protected RRaw doRaw(RRaw operand) { - return RDataFactory.createRaw(performRaw(operand)); - } - - @SuppressWarnings("unused") - @Specialization - protected Object doNull(RNull operand) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE); - } - - private static byte performRaw(RRaw operand) { + private static byte notRaw(RRaw operand) { return (byte) (255 - operand.getValue()); } @Specialization - protected RLogicalVector performLogicalVectorNot(@SuppressWarnings("unused") RFunction operand) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE); + protected byte doLogical(byte operand) { + return naProfile.isNA(operand) ? RRuntime.LOGICAL_NA : not(operand); } - @Specialization(guards = "isZeroLength") - protected RLogicalVector performLogicalVectorNot(@SuppressWarnings("unused") RAbstractVector vector) { - return RDataFactory.createEmptyLogicalVector(); + @Specialization + protected byte doInt(int operand) { + return naProfile.isNA(operand) ? RRuntime.LOGICAL_NA : not(operand); } @Specialization - protected RLogicalVector performLogicalVectorNot(@SuppressWarnings("unused") RAbstractStringVector vector) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE); + protected byte doDouble(double operand) { + return naProfile.isNA(operand) ? RRuntime.LOGICAL_NA : not(operand); } @Specialization - protected RLogicalVector performLogicalVectorNot(@SuppressWarnings("unused") RList list) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE); + protected RRaw doRaw(RRaw operand) { + return RDataFactory.createRaw(notRaw(operand)); } - @Specialization(guards = "!isZeroLength") + @Specialization protected RLogicalVector doLogicalVector(RLogicalVector vector) { - return performLogicalVectorNot(vector); - } - - @Specialization(guards = "!isZeroLength") - protected RLogicalVector doIntVector(RIntVector vector) { - return performAbstractIntVectorNot(vector); - } - - @Specialization(guards = "!isZeroLength") - protected RLogicalVector doDoubleVector(RDoubleVector vector) { - return performAbstractDoubleVectorNot(vector); - } - - @Specialization(guards = "!isZeroLength") - protected RLogicalVector doIntSequence(RIntSequence vector) { - return performAbstractIntVectorNot(vector); - } - - @Specialization(guards = "!isZeroLength") - protected RLogicalVector doDoubleSequence(RDoubleSequence vector) { - return performAbstractDoubleVectorNot(vector); - } - - @Specialization(guards = "!isZeroLength") - protected RRawVector doRawVector(RRawVector vector) { - return performRawVectorNot(vector); - } - - private RLogicalVector performLogicalVectorNot(RLogicalVector vector) { - na.enable(vector); int length = vector.getLength(); - byte[] result = new byte[length]; - for (int i = 0; i < length; ++i) { - byte value = vector.getDataAt(i); - result[i] = doLogical(value); + byte[] result; + if (zeroLengthProfile.profile(length == 0)) { + result = RDataFactory.EMPTY_LOGICAL_ARRAY; + } else { + na.enable(vector); + result = new byte[length]; + for (int i = 0; i < length; ++i) { + byte value = vector.getDataAt(i); + result[i] = na.check(value) ? RRuntime.LOGICAL_NA : not(value); + } } RLogicalVector resultVector = RDataFactory.createLogicalVector(result, na.neverSeenNA()); resultVector.copyAttributesFrom(vector); return resultVector; } - private RLogicalVector performAbstractIntVectorNot(RAbstractIntVector vector) { - na.enable(vector); + @Specialization + protected RLogicalVector doIntVector(RAbstractIntVector vector) { int length = vector.getLength(); - byte[] result = new byte[length]; - for (int i = 0; i < length; ++i) { - int value = vector.getDataAt(i); - result[i] = doInt(value); + byte[] result; + if (zeroLengthProfile.profile(length == 0)) { + result = RDataFactory.EMPTY_LOGICAL_ARRAY; + } else { + na.enable(vector); + result = new byte[length]; + for (int i = 0; i < length; ++i) { + int value = vector.getDataAt(i); + result[i] = na.check(value) ? RRuntime.LOGICAL_NA : not(value); + } } RLogicalVector resultVector = RDataFactory.createLogicalVector(result, na.neverSeenNA()); resultVector.copyNamesDimsDimNamesFrom(vector, getSourceSection()); return resultVector; } - private RLogicalVector performAbstractDoubleVectorNot(RAbstractDoubleVector vector) { - na.enable(vector); + @Specialization + protected RLogicalVector doDoubleVector(RAbstractDoubleVector vector) { int length = vector.getLength(); - byte[] result = new byte[length]; - for (int i = 0; i < length; ++i) { - double value = vector.getDataAt(i); - result[i] = doDouble(value); + byte[] result; + if (zeroLengthProfile.profile(length == 0)) { + result = RDataFactory.EMPTY_LOGICAL_ARRAY; + } else { + na.enable(vector); + result = new byte[length]; + for (int i = 0; i < length; ++i) { + double value = vector.getDataAt(i); + result[i] = na.check(value) ? RRuntime.LOGICAL_NA : not(value); + } } RLogicalVector resultVector = RDataFactory.createLogicalVector(result, na.neverSeenNA()); - resultVector.copyNamesFrom(vector); + resultVector.copyNamesDimsDimNamesFrom(vector, getSourceSection()); return resultVector; } - private RRawVector performRawVectorNot(RRawVector vector) { - na.enable(vector); + @Specialization + protected RRawVector doRawVector(RRawVector vector) { int length = vector.getLength(); - byte[] result = new byte[length]; - for (int i = 0; i < length; ++i) { - RRaw value = vector.getDataAt(i); - result[i] = performRaw(value); + byte[] result; + if (zeroLengthProfile.profile(length == 0)) { + result = RDataFactory.EMPTY_RAW_ARRAY; + } else { + result = new byte[length]; + for (int i = 0; i < length; ++i) { + result[i] = notRaw(vector.getDataAt(i)); + } } RRawVector resultVector = RDataFactory.createRawVector(result); resultVector.copyAttributesFrom(vector); return resultVector; } - private static byte not(byte value) { - return (value == RRuntime.LOGICAL_TRUE ? RRuntime.LOGICAL_FALSE : RRuntime.LOGICAL_TRUE); + @Specialization(guards = {"isZeroLength"}) + protected RLogicalVector doStringVector(@SuppressWarnings("unused") RAbstractStringVector vector) { + return RDataFactory.createEmptyLogicalVector(); + } + + @Specialization(guards = {"isZeroLength"}) + protected RLogicalVector doComplexVector(@SuppressWarnings("unused") RAbstractComplexVector vector) { + return RDataFactory.createEmptyLogicalVector(); + } + + @Specialization(guards = {"isZeroLength"}) + protected RLogicalVector doList(@SuppressWarnings("unused") RList list) { + return RDataFactory.createEmptyLogicalVector(); } protected boolean isZeroLength(RAbstractVector vector) { return vector.getLength() == 0; } + + @Fallback + protected Object invalidArgType(@SuppressWarnings("unused") Object operand) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE); + } } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/gnfi/GNFI_RFFIFactory.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/gnfi/GNFI_RFFIFactory.java index b574ed3fc36ba76e177bdf187226e88d9a67cc49..bc5608771aa4dd316533880c0257e2b16828da16 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/gnfi/GNFI_RFFIFactory.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/gnfi/GNFI_RFFIFactory.java @@ -139,7 +139,7 @@ public class GNFI_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI { return null; } else { // some other error - throw ioex(); + throw ioex(null); } } else { return CString.create(resultBuf.address, length, false); @@ -187,4 +187,13 @@ public class GNFI_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI { return 0; } + public void mkdir(String dir, int mode) throws IOException { + Utils.fail("mkdir not implemented"); + } + + public long strtol(String s, int base) throws IllegalArgumentException { + Utils.fail("strtol not implemented"); + return 0; + } + } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java index c706d3175516eada57c038384cf3c66d66c8dffa..6af93ea3926be667bee2cfb1fd44b78f13f63071 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java @@ -61,6 +61,8 @@ public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, RDer int getcwd(@Out byte[] path); long mkdtemp(@In @Out ByteBuffer template); + + long strtol(@In String dir, @In String end, int base); } private static class LibCXProvider { @@ -127,7 +129,7 @@ public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, RDer // not a link } else { // some other error - throw ioex(); + throw ioex(Errno.valueOf(n).description()); } } return s; @@ -143,6 +145,25 @@ public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, RDer } } + public void mkdir(String dir, int mode) throws IOException { + try { + posix().mkdir(dir, mode); + } catch (RuntimeException ex) { + throw ioex(Errno.valueOf(posix().errno()).description()); + } + } + + public long strtol(String s, int base) throws IllegalArgumentException { + posix().errno(0); + long result = libcx().strtol(s, null, base); + int e = posix().errno(); + if (e != 0) { + throw new IllegalArgumentException(Errno.valueOf(e).description()); + } else { + return result; + } + } + public Object dlopen(String path, boolean local, boolean now) { int flags = (local ? com.kenai.jffi.Library.LOCAL : com.kenai.jffi.Library.GLOBAL) | (now ? com.kenai.jffi.Library.NOW : com.kenai.jffi.Library.LAZY); return com.kenai.jffi.Library.getCachedInstance(path, flags); @@ -631,4 +652,5 @@ public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, RDer public int uncompress(byte[] dest, long[] destlen, byte[] source) { return zip().uncompress(dest, destlen, source, source.length); } + } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java index c5ea07be92d6dff51336e2e7854a6a1dc10c2c5f..d7ae5ec067ca56b881ee81d3ea2f997a20ae5a35 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java @@ -37,6 +37,10 @@ public final class RDataFactory { private static final RStringVector EMPTY_STRING_VECTOR = createStringVector(0); private static final RComplexVector EMPTY_COMPLEX_VECTOR = createComplexVector(0); private static final RRawVector EMPTY_RAW_VECTOR = createRawVector(0); + + public static final byte[] EMPTY_RAW_ARRAY = new byte[0]; + public static final byte[] EMPTY_LOGICAL_ARRAY = new byte[0]; + public static final boolean INCOMPLETE_VECTOR = false; public static final boolean COMPLETE_VECTOR = true; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java index 01d255ec9f3bda6a3576941602261859e71f019a..9773ffb566b7d0310194ddd3f6346172a4607793 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java @@ -44,6 +44,11 @@ public interface BaseRFFI { */ int setwd(String dir); + /** + * Create directory with given mode. Exception is thrown omn error. + */ + void mkdir(String dir, int mode) throws IOException; + /** * Try to convert a symbolic link to it's target. * @@ -94,4 +99,9 @@ public interface BaseRFFI { */ int uncompress(byte[] dest, long[] destlen, byte[] source); + /** + * Convert string to long. + */ + long strtol(String s, int base) throws IllegalArgumentException; + } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java index be62aad8b1c6b78fde58a9d57bf678535eed5fd7..260708527272070f6ad9222020015118fde0ed41 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java @@ -82,8 +82,8 @@ public abstract class RFFIFactory { } @TruffleBoundary - protected static IOException ioex() throws IOException { - throw new IOException(); + protected static IOException ioex(String errMsg) throws IOException { + throw new IOException(errMsg); } } 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 6f9e43f33559d184b61fcb525ed04a411f81f8a3..4c1ccfdf8c12d6f6bf890a50e93c33bec3edaa71 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 @@ -1407,6 +1407,14 @@ complex(0) #{ -c((1+0i)/0,2) } [1] NaN+NaNi -2+ 0i +##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryMinusDimensions +#{ xx <- double(0); dim(xx) <- c(0,0); dim(-xx) } +[1] 0 0 + +##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryMinusDimensions +#{ xx <- double(1); dim(xx) <- c(1,1); dim(-xx) } +[1] 1 1 + ##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryMinusErrors #{ f <- function(z) { -z } ; f(1:3) ; f("hello") } Error in -z : invalid argument to unary operator @@ -1435,6 +1443,14 @@ Error in -z : invalid argument to unary operator #{ !TRUE } [1] FALSE +##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryNotDimensions +#{ xx <- double(0); dim(xx) <- c(0,0); dim(!xx) } +[1] 0 0 + +##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryNotDimensions +#{ xx <- double(1); dim(xx) <- c(1,1); dim(!xx) } +[1] 1 1 + ##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryNotError #{ l <- c("hello", "hi") ; !l } Error in !l : invalid argument type @@ -6089,6 +6105,12 @@ hi 1 2 3 hello ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat #{ cat("hi",1[2],"hello",sep="-") } hi-NA-hello +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat +#{ cat("hi",1[2],"hello",sep="-\n") } +hi- +NA- +hello + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat #{ cat() } @@ -6098,6 +6120,10 @@ hi-NA-hello ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat #{ cat(1, "a") } 1 a +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat +#{ cat(1, sep="\n") } +1 + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat #{ cat(1,2,3) } 1 2 3 @@ -6156,6 +6182,21 @@ hello ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat #{ m <- matrix(as.character(1:6), nrow=2) ; cat(m) } 1 2 3 4 5 6 +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCatVarargs +#{ f <- function(...) {cat(...,sep="-")}; f("a") } +a +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCatVarargs +#{ f <- function(...) {cat(...,sep="-")}; f("a", "b") } +a-b +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCatVarargs +#{ f <- function(...) {cat(...,sep="-\n")}; f("a") } +a + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCatVarargs +#{ f <- function(...) {cat(...,sep="-\n")}; f("a", "b") } +a- +b + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCbind #{ cbind() } NULL @@ -8532,6 +8573,10 @@ NULL #{ inherits(new.env(), "try-error") } [1] FALSE +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testInherits +#{ inherits(textConnection("abc"), "connection") } +[1] TRUE + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testInherits #{ x<-data.frame(c(1,2)); inherits(x, "data.frame") } [1] TRUE diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java index c50e14f06b1da06a2898cd234833034c791a97a9..d0877e00e11531382d33c697fb23ffc48ada1ce3 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java @@ -1733,6 +1733,16 @@ public class AllTests extends TestBase { assertEval("{ -c((1+0i)/0,2) }"); } + @Test + public void TestSimpleArithmetic_testUnaryMinusDimensions_82d8cc2dfa20802f3af03d30533599c1() { + assertEval("{ xx <- double(0); dim(xx) <- c(0,0); dim(-xx) }"); + } + + @Test + public void TestSimpleArithmetic_testUnaryMinusDimensions_1c0bc1dd2399b5dd2298ffe8d8da94c2() { + assertEval("{ xx <- double(1); dim(xx) <- c(1,1); dim(-xx) }"); + } + @Test public void TestSimpleArithmetic_testUnaryMinusErrors_c1f5e118009944a5b67f947745697a4a() { assertEvalError("{ z <- \"hello\" ; -z }"); @@ -1768,6 +1778,16 @@ public class AllTests extends TestBase { assertEval("{ !NA }"); } + @Test + public void TestSimpleArithmetic_testUnaryNotDimensions_c06858978ee19736bc28f17e7c3acf08() { + assertEval("{ xx <- double(0); dim(xx) <- c(0,0); dim(!xx) }"); + } + + @Test + public void TestSimpleArithmetic_testUnaryNotDimensions_e16c9de9476e28643ba613022602d2a6() { + assertEval("{ xx <- double(1); dim(xx) <- c(1,1); dim(!xx) }"); + } + @Test public void TestSimpleArithmetic_testUnaryNotError_e1de893845dc88297503728fe5d2e03c() { assertEval("{ x<-1:4; dim(x)<-c(2, 2); names(x)<-101:104; attr(x, \"dimnames\")<-list(c(\"201\", \"202\"), c(\"203\", \"204\")); attr(x, \"foo\")<-\"foo\"; y<-!x; attributes(y) }"); @@ -5683,6 +5703,11 @@ public class AllTests extends TestBase { assertEvalNoNL("{ cat(1) }"); } + @Test + public void TestSimpleBuiltins_testCat_5cd9f21c97025b5427f8244d0c0e0ffc() { + assertEvalNoNL("{ cat(1, sep=\"\\n\") }"); + } + @Test public void TestSimpleBuiltins_testCat_f48953c23109705840adb64bc147151b() { assertEvalNoNL("{ cat(1,2,3) }"); @@ -5788,6 +5813,11 @@ public class AllTests extends TestBase { assertEvalNoNL("{ cat(\"hi\",1[2],\"hello\",sep=\"-\") }"); } + @Test + public void TestSimpleBuiltins_testCat_91de7df676b06ad665ce3584e334842c() { + assertEvalNoNL("{ cat(\"hi\",1[2],\"hello\",sep=\"-\\n\") }"); + } + @Test public void TestSimpleBuiltins_testCat_1dcd33ce696ea60d54dd157e9d0dd76f() { assertEvalNoNL("{ m <- matrix(as.character(1:6), nrow=2) ; cat(m) }"); @@ -5813,6 +5843,26 @@ public class AllTests extends TestBase { assertEvalNoNL("{ cat(\"hi\",integer(0),\"hello\",sep=\"-\") }"); } + @Test + public void TestSimpleBuiltins_testCatVarargs_ff51d78a6902080ce5f8721aa9bd9932() { + assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\")}; f(\"a\") }"); + } + + @Test + public void TestSimpleBuiltins_testCatVarargs_a217c0f15c1bc137c95929aaed1c51f2() { + assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\\n\")}; f(\"a\") }"); + } + + @Test + public void TestSimpleBuiltins_testCatVarargs_ca16199a5bf10ef8a2fccd05debcaf73() { + assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\")}; f(\"a\", \"b\") }"); + } + + @Test + public void TestSimpleBuiltins_testCatVarargs_782dd61fabc4402b2636903c37f05fe6() { + assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\\n\")}; f(\"a\", \"b\") }"); + } + @Test public void TestSimpleBuiltins_testCbind_b6d50b783340cfd840b5d0d1c478e85a() { assertEval("{ cbind() }"); @@ -8453,6 +8503,11 @@ public class AllTests extends TestBase { assertEval("{ x<-factor(\"a\", \"b\", \"a\"); inherits(x, \"factor\") }"); } + @Test + public void TestSimpleBuiltins_testInherits_34ff95edf55241d7710a1123747655e8() { + assertEval("{ inherits(textConnection(\"abc\"), \"connection\") }"); + } + @Test public void TestSimpleBuiltins_testInheritsIgnore_d0dc6389c924878311546ba61d753a22() { assertEval("{x <- 10;class(x) <- c(\"a\", \"b\");inherits(x, 2, c(TRUE)) ;}"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleArithmetic.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleArithmetic.java index 46c3b442bdf322e1f7dd01c4b2a2551da2b3dcc3..a023c8f078d86df0fed71ee225e5b2762820112d 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleArithmetic.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleArithmetic.java @@ -374,6 +374,12 @@ public class TestSimpleArithmetic extends TestBase { assertEval("{ x<-1:4; dim(x)<-c(2, 2); names(x)<-101:104; attr(x, \"dimnames\")<-list(201:202, 203:204); attr(x, \"foo\")<-\"foo\"; y<-!x; attributes(y) }"); } + @Test + public void testUnaryNotDimensions() { + assertEval("{ xx <- double(0); dim(xx) <- c(0,0); dim(!xx) }"); + assertEval("{ xx <- double(1); dim(xx) <- c(1,1); dim(!xx) }"); + } + @Test public void testUnaryMinus() { assertEval("{ -3 }"); @@ -425,6 +431,12 @@ public class TestSimpleArithmetic extends TestBase { assertEvalError("{ f <- function(z) { -z } ; f(1:3) ; f(\"hello\") }"); } + @Test + public void testUnaryMinusDimensions() { + assertEval("{ xx <- double(0); dim(xx) <- c(0,0); dim(-xx) }"); + assertEval("{ xx <- double(1); dim(xx) <- c(1,1); dim(-xx) }"); + } + @Test public void testMatrices() { assertEval("{ m <- matrix(1:6, nrow=2, ncol=3, byrow=TRUE) ; m-1 }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java index 0d91359ab0ee78284e322286a96b087bc622fa5e..5dd75c552a11ce6c653d2c4f29b6e33b42e8b4ba 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java @@ -965,6 +965,7 @@ public class TestSimpleBuiltins extends TestBase { public void testCat() { assertEvalNoOutput("{ cat() }"); assertEvalNoNL("{ cat(1) }"); + assertEvalNoNL("{ cat(1, sep=\"\\n\") }"); assertEvalNoNL("{ cat(1,2,3) }"); assertEvalNoNL("{ cat(\"a\") }"); assertEvalNoNL("{ cat(\"a\", \"b\") }"); @@ -986,11 +987,20 @@ public class TestSimpleBuiltins extends TestBase { assertEvalNoNL("{ cat(c(1L, 2L, 3L)) }"); assertEvalNoNL("{ cat(1,2,sep=\".\") }"); assertEvalNoNL("{ cat(\"hi\",1[2],\"hello\",sep=\"-\") }"); + assertEvalNoNL("{ cat(\"hi\",1[2],\"hello\",sep=\"-\\n\") }"); assertEvalNoNL("{ m <- matrix(as.character(1:6), nrow=2) ; cat(m) }"); assertEvalNoNL("{ cat(sep=\" \", \"hello\") }"); assertEval("{ cat(rep(NA, 8), \"Hey\",\"Hey\",\"Goodbye\",\"\\n\") }"); } + @Test + public void testCatVarargs() { + assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\")}; f(\"a\") }"); + assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\\n\")}; f(\"a\") }"); + assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\")}; f(\"a\", \"b\") }"); + assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\\n\")}; f(\"a\", \"b\") }"); + } + @Test @Ignore public void testCatIgnore() { @@ -3297,6 +3307,7 @@ public class TestSimpleBuiltins extends TestBase { assertEval("{ x<-data.frame(c(1,2)); inherits(x, \"data.frame\") }"); assertEval("{ x<-factor(\"a\", \"b\", \"a\"); inherits(x, \"factor\") }"); + assertEval("{ inherits(textConnection(\"abc\"), \"connection\") }"); } @Test