diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/GraphicsCCalls.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/GraphicsCCalls.java index f8be136a75fc078dd576958b1379fe5d2cb0da81..cf5fd17e357659cdeba3406e0bab791e19f46a3c 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/GraphicsCCalls.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/GraphicsCCalls.java @@ -14,20 +14,34 @@ */ package com.oracle.truffle.r.library.graphics; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.library.graphics.core.*; import com.oracle.truffle.r.library.graphics.core.geometry.*; +import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; public class GraphicsCCalls { - public static void plotXy(RDoubleVector xyVector) { - assert xyVector.getLength() % 2 == 0 : "wrong size of vector"; - getGraphicsEngine().setCurrentGraphicsDeviceMode(GraphicsDevice.Mode.GRAPHICS_ON); - drawWithLines(xyVector); + public static final class C_PlotXY extends RExternalBuiltinNode { + + @Override + @TruffleBoundary + public RNull call(RArgsValuesAndNames args) { + RDoubleVector xyVector = ((RAbstractDoubleVector) args.getArgument(0)).materialize(); + assert xyVector.getLength() % 2 == 0 : "wrong size of vector"; + getGraphicsEngine().setCurrentGraphicsDeviceMode(GraphicsDevice.Mode.GRAPHICS_ON); + drawWithLines(xyVector); + return RNull.instance; + } } - public static Object par(@SuppressWarnings("unused") RArgsValuesAndNames args) { - // pch - return RDataFactory.createIntVectorFromScalar(1); + public static final class C_Par extends RExternalBuiltinNode { + + @Override + public Object call(RArgsValuesAndNames args) { + // pch + return RDataFactory.createIntVectorFromScalar(1); + } } private static void drawWithLines(RDoubleVector xyVector) { @@ -55,5 +69,4 @@ public class GraphicsCCalls { private static GraphicsEngine getGraphicsEngine() { return GraphicsEngineImpl.getInstance(); } - } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java index 6315dfffec79dacc192e648a93471de2e470a9db..8a3d73eefe196f322398f85b15c807c433f094bc 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java @@ -11,57 +11,93 @@ */ package com.oracle.truffle.r.library.methods; +import com.oracle.truffle.api.CompilerDirectives.*; +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.env.*; // Transcribed from src/library/methods/methods_list_dispatch.c public class MethodsListDispatch { - private static MethodsListDispatch singleton = new MethodsListDispatch(); - private boolean tableDispatchOn = true; + public abstract static class R_initMethodDispatch extends RExternalBuiltinNode.Arg1 { - public static MethodsListDispatch getInstance() { - return singleton; + @Specialization + @TruffleBoundary + protected REnvironment initMethodDispatch(REnvironment env) { + // TBD what should we actually do here + return env; + } } - public REnvironment initMethodDispatch(REnvironment env) { - // TODO initialize - return env; + public abstract static class R_methodsPackageMetaName extends RExternalBuiltinNode.Arg3 { + + @TruffleBoundary + @Specialization + protected String callMethodsPackageMetaName(String prefixString, String nameString, String pkgString) { + if (pkgString.length() == 0) { + return ".__" + prefixString + "__" + nameString; + } else { + return ".__" + prefixString + "__" + nameString + ":" + pkgString; + } + } } - public byte setMethodDispatch(byte onOff) { - boolean prev = tableDispatchOn; + public abstract static class R_getClassFromCache extends RExternalBuiltinNode.Arg2 { - if (onOff == RRuntime.LOGICAL_NA) { - return RRuntime.asLogical(prev); - } - boolean value = RRuntime.fromLogical(onOff); - tableDispatchOn = value; - if (value != prev) { - // TODO + @TruffleBoundary + @Specialization + protected Object callGetClassFromCache(REnvironment table, Object klass) { + String klassString = RRuntime.asString(klass); + + if (klassString != null) { + Object value = table.get(klassString); + if (value == null) { + return RNull.instance; + } else { + // TODO check PACKAGE equality + return value; + } + } else { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE); + } } - return RRuntime.asLogical(prev); } - public String methodsPackageMetaName(String prefixString, String nameString, String pkgString) { - if (pkgString.length() == 0) { - return String.format(".__%s__%s", prefixString, nameString); - } else { - return String.format(".__%s__%s:%s", prefixString, nameString, pkgString); + public abstract static class R_set_method_dispatch extends RExternalBuiltinNode.Arg1 { + + @TruffleBoundary + @Specialization + protected Object callSetMethodDispatch(RAbstractLogicalVector onOffVector) { + boolean prev = RContext.getInstance().isMethodTableDispatchOn(); + byte onOff = castLogical(onOffVector); + + if (onOff == RRuntime.LOGICAL_NA) { + return RRuntime.asLogical(prev); + } + boolean value = RRuntime.fromLogical(onOff); + RContext.getInstance().setMethodTableDispatchOn(value); + if (value != prev) { + // TODO + } + return RRuntime.asLogical(prev); } } - public Object getClassFromCache(REnvironment table, String klassString) { - Object value = table.get(klassString); - if (value == null) { + public abstract static class R_M_setPrimitiveMethods extends RExternalBuiltinNode.Arg5 { + + @SuppressWarnings("unused") + @Specialization + @TruffleBoundary + protected Object setPrimitiveMethods(Object fname, Object op, Object codeVec, RFunction fundef, Object mlist) { + String fnameString = RRuntime.asString(fname); + String codeVecString = RRuntime.asString(codeVec); + + // TODO implement return RNull.instance; - } else { - // TODO check PACKAGE equality - return value; } - } - } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/SetPrimitiveMethods.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/SetPrimitiveMethods.java deleted file mode 100644 index 54d302e7155d6ba4046feab8c226f1fa526deafa..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/SetPrimitiveMethods.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2013, 2015, 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.library.methods; - -import com.oracle.truffle.r.runtime.data.*; - -public class SetPrimitiveMethods { - @SuppressWarnings("unused") - public static Object doit(String fname, Object op, String codeVec, RFunction fundef, Object mlist) { - // TODO implement - return RNull.instance; - } -} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java index d22ff41dacd73d10a0697a491c072ae39a6277ed..8c111c183e76b9ec548dd03022b8dc6b55e403d5 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java @@ -13,15 +13,39 @@ package com.oracle.truffle.r.library.stats; import com.oracle.truffle.api.source.*; 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.*; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.*; /* * Logic derived from GNU-R, library/stats/src/cov.c */ -public class Covcor { - private static final Covcor singleton = new Covcor(); +public final class Covcor extends RExternalBuiltinNode { + + private final boolean isCor; + + public Covcor(boolean isCor) { + this.isCor = isCor; + } + + @Override + public Object call(RArgsValuesAndNames args) { + Object[] argValues = args.getArguments(); + if (argValues[0] == RNull.instance) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.IS_NULL, "x"); + } + // TODO error checks/coercions + RAbstractDoubleVector x = (RAbstractDoubleVector) argValues[0]; + RAbstractDoubleVector y = argValues[1] == RNull.instance ? null : (RAbstractDoubleVector) argValues[1]; + int method = ((RAbstractIntVector) argValues[2]).getDataAt(0); + if (method != 4) { + throw RError.nyi(getEncapsulatingSourceSection(), "method"); + } + boolean iskendall = RRuntime.fromLogical(castLogical(castVector(argValues[3]))); + return corcov(x.materialize(), y != null ? y.materialize() : null, method, iskendall, getEncapsulatingSourceSection()); + } private final NACheck check = new NACheck(); @@ -35,11 +59,7 @@ public class Covcor { private final BranchProfile error = BranchProfile.create(); private final BranchProfile warning = BranchProfile.create(); - public static Covcor getInstance() { - return singleton; - } - - public RDoubleVector corcov(RDoubleVector x, RDoubleVector y, @SuppressWarnings("unused") int method, boolean iskendall, boolean cor, SourceSection src) throws RError { + public RDoubleVector corcov(RDoubleVector x, RDoubleVector y, @SuppressWarnings("unused") int method, boolean iskendall, SourceSection src) throws RError { boolean ansmat; boolean naFail; boolean everything; @@ -96,20 +116,20 @@ public class Covcor { double[] xm = new double[ncx]; if (y == null) { if (everything) { - sd0 = covNA1(n, ncx, x, xm, answerData, cor, iskendall); + sd0 = covNA1(n, ncx, x, xm, answerData, isCor, iskendall); } else { RIntVector ind = RDataFactory.createIntVector(n); complete1(n, ncx, x, ind, naFail); - sd0 = covComplete1(n, ncx, x, xm, ind, answerData, cor, iskendall); + sd0 = covComplete1(n, ncx, x, xm, ind, answerData, isCor, iskendall); } } else { double[] ym = new double[ncy]; if (everything) { - sd0 = covNA2(n, ncx, ncy, x, y, xm, ym, answerData, cor, iskendall); + sd0 = covNA2(n, ncx, ncy, x, y, xm, ym, answerData, isCor, iskendall); } else { RIntVector ind = RDataFactory.createIntVector(n); complete2(n, ncx, ncy, x, y, ind, naFail); - sd0 = covComplete2(n, ncx, ncy, x, y, xm, ym, ind, answerData, cor, iskendall); + sd0 = covComplete2(n, ncx, ncy, x, y, xm, ym, ind, answerData, isCor, iskendall); } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java index 1ecdb1545f5f2e01800c83a90b8b527d8f35bfd7..1f912aa3e13cd0163e7c2b9b3abccb81a055b55e 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java @@ -20,7 +20,10 @@ package com.oracle.truffle.r.library.stats; import static com.oracle.truffle.r.library.stats.StatsUtil.*; -import com.oracle.truffle.api.CompilerDirectives.*; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.*; +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.*; @@ -36,18 +39,12 @@ public abstract class GammaFunctions { // This is derived from distn.c. - public static class Qgamma { - - private static final Qgamma singleton = new Qgamma(); + public abstract static class Qgamma extends RExternalBuiltinNode.Arg5 { private final NACheck naCheck = NACheck.create(); - public static Qgamma getInstance() { - return singleton; - } - @TruffleBoundary - public RDoubleVector qgamma(RAbstractDoubleVector p, RAbstractDoubleVector shape, RAbstractDoubleVector scale, byte lowerTail, byte logP, RAttributeProfiles attrProfiles) { + private RDoubleVector qgamma(RAbstractDoubleVector p, RAbstractDoubleVector shape, RAbstractDoubleVector scale, byte lowerTail, byte logP) { int pLen = p.getLength(); int shapeLen = shape.getLength(); int scaleLen = scale.getLength(); @@ -69,6 +66,13 @@ public abstract class GammaFunctions { return res; } + @Specialization + public RAbstractDoubleVector qgamma(RAbstractDoubleVector p, RAbstractDoubleVector shape, RAbstractDoubleVector scale, RAbstractLogicalVector lowerTail, RAbstractLogicalVector logP) { + if (shape.getLength() == 0 || scale.getLength() == 0) { + return RDataFactory.createEmptyDoubleVector(); + } + return qgamma(p, shape, scale, castLogical(lowerTail), castLogical(logP)); + } } // The remainder of this file is derived from GNU R (mostly nmath): qgamma.c, nmath.h, lgamma.c, diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java index 1836629ff51d374b9501bb8ffa4c4421db7fb776..98b96b9af21f7ee099c9e535aa0ebf14a15f5824 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java @@ -13,41 +13,11 @@ package com.oracle.truffle.r.library.stats; import static com.oracle.truffle.r.library.stats.StatsUtil.*; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.r.runtime.data.*; -import com.oracle.truffle.r.runtime.rng.*; - /* * Logic derived from GNU-R, see inline comments. */ public class Random2 { - @TruffleBoundary - public static RDoubleVector rnorm(int n, double mean, double standardd) { - double[] result = new double[n]; - for (int i = 0; i < n; i++) { - result[i] = generateNorm(mean, standardd); - } - return RDataFactory.createDoubleVector(result, RDataFactory.COMPLETE_VECTOR); - } - - // from GNUR: rnorm.c - private static double generateNorm(double mean, double standardd) { - return mean + standardd * normRand(); - } - - // from GNUR: snorm.c - private static double normRand() { - double u1; - - // case INVERSION: - double big = 134217728; /* 2^27 */ - /* unif_rand() alone is not of high enough precision */ - u1 = RRNG.unifRand(); - u1 = (int) (big * u1) + RRNG.unifRand(); - return qnorm5(u1 / big, 0.0, 1.0, true, false); - } - // from GNUR: qnorm.c public static double qnorm5(double p, double mu, double sigma, boolean lowerTail, boolean logP) { double pU; @@ -110,5 +80,4 @@ public class Random2 { } return mu + sigma * val; } - } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java new file mode 100644 index 0000000000000000000000000000000000000000..d620d9ea8ef80f256d5ebe20171eeb2078b9cb26 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java @@ -0,0 +1,52 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995-2012, The R Core Team + * Copyright (c) 2003, The R Foundation + * Copyright (c) 2013, 2015, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.stats; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.rng.*; + +/** + * TODO GnuR checks/updates {@code .Random.seed} across this call. TODO Honor min/max. + */ +public abstract class Rnorm extends RExternalBuiltinNode.Arg3 { + + // from GNUR: rnorm.c + private static double generateNorm(double mean, double standardd) { + return mean + standardd * normRand(); + } + + // from GNUR: snorm.c + private static double normRand() { + double u1; + + // case INVERSION: + double big = 134217728; /* 2^27 */ + /* unif_rand() alone is not of high enough precision */ + u1 = RRNG.unifRand(); + u1 = (int) (big * u1) + RRNG.unifRand(); + return Random2.qnorm5(u1 / big, 0.0, 1.0, true, false); + } + + @Specialization + protected Object doRnorm(Object n, double mean, double standardd) { + // TODO full error checks + int nInt = castInt(castVector(n)); + + double[] result = new double[nInt]; + for (int i = 0; i < nInt; i++) { + result[i] = generateNorm(mean, standardd); + } + return RDataFactory.createDoubleVector(result, RDataFactory.COMPLETE_VECTOR); + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java index f99c9b47c34c3c6a83e67cef367da538b73ecb7e..87e0d5d3f9cb025efa5e4ac91c0d9fac4758360f 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java @@ -22,20 +22,28 @@ */ package com.oracle.truffle.r.library.stats; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.rng.*; /** - * TODO GnuR checks/updates {@code .Random.seed} across this call. TODO Honor min/max. + * TODO GnuR checks/updates {@code .Random.seed} across this call. */ -public class Runif { +public abstract class Runif extends RExternalBuiltinNode.Arg3 { - public static RDoubleVector runif(int length, @SuppressWarnings("unused") double min, @SuppressWarnings("unused") double max) { - double[] result = new double[length]; - for (int i = 0; i < length; i++) { - result[i] = RRNG.unifRand(); + @Specialization + protected Object doRunif(Object n, Object min, Object max) { + // TODO full error checks + int nInt = castInt(castVector(n)); + double minDouble = castDouble(castVector(min)).getDataAt(0); + double maxDouble = castDouble(castVector(max)).getDataAt(0); + double delta = maxDouble - minDouble; + + double[] result = new double[nInt]; + for (int i = 0; i < nInt; i++) { + result[i] = minDouble + RRNG.unifRand() * delta; } return RDataFactory.createDoubleVector(result, RDataFactory.COMPLETE_VECTOR); } - } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java index 9ab592fbc034888e26745cf0980cc0b8a3982383..d65e0aaa92877ffd8116c47e0725f6861630b756 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java @@ -11,9 +11,12 @@ */ package com.oracle.truffle.r.library.stats; -import com.oracle.truffle.api.CompilerDirectives.*; +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.ops.*; /** @@ -24,8 +27,27 @@ import com.oracle.truffle.r.runtime.ops.*; */ public class SplineFunctions { - @TruffleBoundary - public static RList splineCoef(int method, RDoubleVector x, RDoubleVector y) { + public abstract static class SplineCoef extends RExternalBuiltinNode.Arg3 { + + @TruffleBoundary + @Specialization + protected Object splineCoef(Object method, RAbstractDoubleVector x, RAbstractDoubleVector y) { + int methodInt = castInt(castVector(method)); + return SplineFunctions.splineCoef(methodInt, x.materialize(), y.materialize()); + } + } + + public abstract static class SplineEval extends RExternalBuiltinNode.Arg2 { + + @TruffleBoundary + @Specialization + protected Object splineEval(RAbstractDoubleVector xout, RList z) { + // This is called with the result of SplineCoef, so it is surely an RList + return SplineFunctions.splineEval(attrProfiles, xout.materialize(), z); + } + } + + private static RList splineCoef(int method, RDoubleVector x, RDoubleVector y) { final int n = x.getLength(); if (y.getLength() != n) { throw RError.error(RError.Message.INPUTS_DIFFERENT_LENGTHS); @@ -63,7 +85,7 @@ public class SplineFunctions { /* * Periodic Spline --------------- The end conditions here match spline (and its derivatives) at * x[1] and x[n]. - * + * * Note: There is an explicit check that the user has supplied data with y[1] equal to y[n]. */ private static void periodicSpline(int n, double[] x, double[] y, double[] b, double[] c, double[] d) { @@ -182,7 +204,7 @@ public class SplineFunctions { /* * Natural Splines --------------- Here the end-conditions are determined by setting the second * derivative of the spline at the end-points to equal to zero. - * + * * There are n-2 unknowns (y[i]'' at x[2], ..., x[n-1]) and n-2 equations to determine them. * Either Choleski or Gaussian elimination could be used. */ @@ -340,7 +362,7 @@ public class SplineFunctions { return; } - public static RDoubleVector splineEval(RAttributeProfiles attrProfiles, RDoubleVector xout, RList z) { + private static RDoubleVector splineEval(RAttributeProfiles attrProfiles, RDoubleVector xout, RList z) { int nu = xout.getLength(); double[] yout = new double[nu]; int method = (int) z.getDataAt(z.getElementIndexByName(attrProfiles, "method")); @@ -356,7 +378,6 @@ public class SplineFunctions { return RDataFactory.createDoubleVector(yout, xout.isComplete() && x.isComplete() && y.isComplete()); } - @TruffleBoundary private static void splineEval(int method, int nu, double[] u, double[] v, int n, double[] x, double[] y, double[] b, double[] c, double[] d) { /* * Evaluate v[l] := spline(u[l], ...), l = 1,..,nu, i.e. 0:(nu-1) Nodes x[i], coef (y[i]; diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsParseRd.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java similarity index 66% rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsParseRd.java rename to com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java index 41e550fda8f1f2408c11a292caec1326cffcb5ac..2313f8e80dadd5ef1aa2a5864b5b08b83c1c4720 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsParseRd.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java @@ -22,14 +22,25 @@ */ package com.oracle.truffle.r.library.tools; +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.conn.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.env.*; -public class ToolsParseRd { +public abstract class C_ParseRd extends RExternalBuiltinNode.Arg7 { + @SuppressWarnings("unused") - public static Object parseRd(RConnection con, REnvironment srcfile, String encoding, boolean verbose, RAbstractStringVector basename, boolean fragment, boolean warningCalls) { + @Specialization + protected Object parseRd(RConnection con, REnvironment srcfile, String encoding, byte verbose, RAbstractStringVector basename, byte fragment, byte warningCalls) { return RNull.instance; } + + @SuppressWarnings("unused") + @Fallback + public Object parseRd(Object con, Object srcfile, Object encoding, Object verbose, Object basename, Object fragment, Object warningCalls) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS); + } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsDirChmod.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/DirChmod.java similarity index 63% rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsDirChmod.java rename to com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/DirChmod.java index 989a524747d9fd5bb7fe614b712cf775c91cba2d..9691ccb32c296e0ad707f417f57c5ba51fee5d8e 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsDirChmod.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/DirChmod.java @@ -17,16 +17,30 @@ import java.nio.file.attribute.*; import java.util.*; import java.util.stream.*; +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.*; -public class ToolsDirChmod { +public abstract class DirChmod extends RExternalBuiltinNode.Arg2 { + private static final int GRPWRITE_FILE_MASK = 0664; private static final int GRPWRITE_DIR_MASK = 0775; private static final int FILE_MASK = 0644; private static final int DIR_MASK = 0755; - public static void dirChmod(String pathName, boolean setGroupWrite) { + @TruffleBoundary + @Specialization + protected RNull dirChmod(RAbstractStringVector dir, Object gws) { + if (dir.getLength() != 1) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "dir"); + } + String pathName = ((RStringVector) dir).getDataAt(0); + boolean setGroupWrite = RRuntime.fromLogical(castLogical(castVector(gws))); + Path path = FileSystems.getDefault().getPath(pathName); int fileMask = setGroupWrite ? GRPWRITE_FILE_MASK : FILE_MASK; int dirMask = setGroupWrite ? GRPWRITE_DIR_MASK : DIR_MASK; @@ -41,12 +55,18 @@ public class ToolsDirChmod { PosixFileAttributes pfa = Files.readAttributes(element, PosixFileAttributes.class); int elementMode = Utils.intFilePermissions(pfa.permissions()); int newMode = Files.isDirectory(element) ? elementMode | dirMask : elementMode | fileMask; -// System.out.printf("path %s: old %o, new %o%n", element, elementMode, newMode); + // System.out.printf("path %s: old %o, new %o%n", element, elementMode, newMode); RFFIFactory.getRFFI().getBaseRFFI().chmod(element.toString(), newMode); } } catch (IOException ex) { // ignore } + return RNull.instance; + } + @SuppressWarnings("unused") + @Fallback + protected Object fallback(Object dir, Object gws) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "dir"); } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsRmd5.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/Rmd5.java similarity index 89% rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsRmd5.java rename to com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/Rmd5.java index 4ab5cb6b4106348ab9c4cbf0b6aef3275df59e34..4767f7201a7db2fe5d2e9f42d37399c3dc44c5cb 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsRmd5.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/Rmd5.java @@ -26,12 +26,17 @@ import java.io.*; import java.security.*; 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.*; -public class ToolsRmd5 { +public abstract class Rmd5 extends RExternalBuiltinNode.Arg1 { + + @Specialization @TruffleBoundary - public static RStringVector rmd5(RStringVector files) { + protected RStringVector rmd5(RAbstractStringVector files) { MessageDigest digest; boolean complete = RDataFactory.COMPLETE_VECTOR; try { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsText.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsText.java index 7927973e42e3e103186a146caf26e1ac6029e47f..b30d8b603d19fcca3021808a234b31b365130755 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsText.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsText.java @@ -13,76 +13,96 @@ package com.oracle.truffle.r.library.tools; import java.io.*; -import com.oracle.truffle.api.CompilerDirectives.*; +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.*; public class ToolsText { - public static RStringVector doTabExpand(RStringVector strings, RIntVector starts) { - String[] data = new String[strings.getLength()]; - for (int i = 0; i < data.length; i++) { - String input = strings.getDataAt(i); - if (input.indexOf('\t') >= 0) { - StringBuffer sb = new StringBuffer(); - int b = 0; - int start = starts.getDataAt(i % data.length); - for (int sx = 0; sx < input.length(); sx++) { - char ch = input.charAt(sx); - if (ch == '\n') { - start = -b - 1; - } - if (ch == '\t') { - do { - sb.append(' '); + + public abstract static class DoTabExpand extends RExternalBuiltinNode.Arg2 { + + @TruffleBoundary + @Specialization + protected Object doTabExpand(RAbstractStringVector strings, RAbstractIntVector starts) { + String[] data = new String[strings.getLength()]; + for (int i = 0; i < data.length; i++) { + String input = strings.getDataAt(i); + if (input.indexOf('\t') >= 0) { + StringBuffer sb = new StringBuffer(); + int b = 0; + int start = starts.getDataAt(i % data.length); + for (int sx = 0; sx < input.length(); sx++) { + char ch = input.charAt(sx); + if (ch == '\n') { + start = -b - 1; + } + if (ch == '\t') { + do { + sb.append(' '); + b++; + } while (((b + start) & 7) != 0); + } else { + sb.append(ch); b++; - } while (((b + start) & 7) != 0); - } else { - sb.append(ch); - b++; + } } + data[i] = sb.toString(); + } else { + data[i] = input; } - data[i] = sb.toString(); - } else { - data[i] = input; } + return RDataFactory.createStringVector(data, RDataFactory.COMPLETE_VECTOR); } - return RDataFactory.createStringVector(data, RDataFactory.COMPLETE_VECTOR); } - @TruffleBoundary - public static RLogicalVector filesAppendLF(String file1, RStringVector file2Vec) { - int n2 = file2Vec.getLength(); - byte[] data = new byte[n2]; - if (!RRuntime.isNA(file1)) { - try (BufferedWriter out = new BufferedWriter(new FileWriter(file1, true))) { - for (int i = 0; i < file2Vec.getLength(); i++) { - String path2 = file2Vec.getDataAt(i); - if (RRuntime.isNA(path2)) { - continue; - } - File path2File = new File(path2); - if (!(path2File.exists() && path2File.canRead())) { - continue; - } - char[] path2Data = new char[(int) path2File.length()]; - try (BufferedReader in = new BufferedReader(new FileReader(path2File))) { - out.write("#line 1 \"" + path2 + "\"\n"); - in.read(path2Data); - out.write(path2Data); - if (!(path2Data.length > 0 && path2Data[path2Data.length - 1] == '\n')) { - out.write('\n'); + public abstract static class CodeFilesAppend extends RExternalBuiltinNode.Arg2 { + + @TruffleBoundary + @Specialization + protected Object codeFilesAppend(RAbstractStringVector file1Vector, RAbstractStringVector file2) { + if (file1Vector.getLength() != 1) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "file1"); + } + if (file2.getLength() < 1) { + return RDataFactory.createEmptyLogicalVector(); + } + String file1 = file1Vector.getDataAt(0); + int n2 = file2.getLength(); + byte[] data = new byte[n2]; + if (!RRuntime.isNA(file1)) { + try (BufferedWriter out = new BufferedWriter(new FileWriter(file1, true))) { + for (int i = 0; i < file2.getLength(); i++) { + String path2 = file2.getDataAt(i); + if (RRuntime.isNA(path2)) { + continue; + } + File path2File = new File(path2); + if (!(path2File.exists() && path2File.canRead())) { + continue; + } + char[] path2Data = new char[(int) path2File.length()]; + try (BufferedReader in = new BufferedReader(new FileReader(path2File))) { + out.write("#line 1 \"" + path2 + "\"\n"); + in.read(path2Data); + out.write(path2Data); + if (!(path2Data.length > 0 && path2Data[path2Data.length - 1] == '\n')) { + out.write('\n'); + } + data[i] = RRuntime.LOGICAL_TRUE; + } catch (IOException ex) { + RError.warning(RError.Message.GENERIC, "write error during file append"); + // shouldn't happen, just continue with false result } - data[i] = RRuntime.LOGICAL_TRUE; - } catch (IOException ex) { - RError.warning(RError.Message.GENERIC, "write error during file append"); - // shouldn't happen, just continue with false result - } + } + } catch (IOException ex) { + // just return logical false } - } catch (IOException ex) { - // just return logical false } + return RDataFactory.createLogicalVector(data, RDataFactory.COMPLETE_VECTOR); } - return RDataFactory.createLogicalVector(data, RDataFactory.COMPLETE_VECTOR); } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/CountFields.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/CountFields.java index e9f0b0967f94badb5b7c7deb3804fd49f043afd9..b14e6ce0da32a57a8069127f2c71619ca8ebc426 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/CountFields.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/CountFields.java @@ -14,6 +14,7 @@ package com.oracle.truffle.r.library.utils; import java.io.*; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.conn.*; import com.oracle.truffle.r.runtime.data.*; @@ -21,11 +22,12 @@ import com.oracle.truffle.r.runtime.data.*; // Transcribed from GnuR, library/utils/src/io.c // Checkstyle: stop -@SuppressWarnings("unused") -public class CountFields { +public final class CountFields extends RExternalBuiltinNode { + private static final int R_EOF = -1; private static final int SCAN_BLOCKSIZE = 1000; + @SuppressWarnings("unused") private static class LocalData { Object NAstrings; boolean quiet; @@ -47,7 +49,7 @@ public class CountFields { } @TruffleBoundary - public static Object execute(RConnection file, char sepChar, String quoteSet, int nskip, boolean blskip, char comChar) throws IOException { + private static Object countFields(RConnection file, char sepChar, String quoteSet, @SuppressWarnings("unused") int nskip, boolean blskip, char comChar) throws IOException { LocalData data = new LocalData(); data.sepchar = sepChar; data.comchar = comChar; @@ -181,7 +183,7 @@ public class CountFields { return c; } - private static void unscanchar(int c, LocalData d) throws IOException { + private static void unscanchar(int c, LocalData d) { d.save = c; } @@ -282,4 +284,61 @@ public class CountFields { return false; } + // Transcribed from GnuR, library/utils/src/io.c + @Override + public Object call(RArgsValuesAndNames args) { + Object[] argValues = args.getArguments(); + RConnection conn = (RConnection) argValues[0]; + Object sepArg = argValues[1]; + char sepChar; + Object quoteArg = argValues[2]; + int nskip = castInt(castVector(argValues[3])); + byte blskip = castLogical(castVector(argValues[4])); + String commentCharArg = isString(argValues[5]); + char comChar; + if (!(commentCharArg != null && commentCharArg.length() == 1)) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "comment.char"); + } else { + comChar = commentCharArg.charAt(0); + } + + if (nskip < 0 || nskip == RRuntime.INT_NA) { + nskip = 0; + } + if (blskip == RRuntime.LOGICAL_NA) { + blskip = RRuntime.LOGICAL_TRUE; + } + + if (sepArg instanceof RNull) { + sepChar = 0; + } else { + String s = isString(sepArg); + if (s == null) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "sep"); + } else { + if (s.length() == 0) { + sepChar = 0; + } else { + sepChar = s.charAt(0); + } + } + } + String quoteSet; + if (quoteArg instanceof RNull) { + quoteSet = ""; + } else { + String s = isString(quoteArg); + if (s == null) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, "invalid quote symbol set"); + } else { + quoteSet = s; + } + } + try (RConnection openConn = conn.forceOpen("r")) { + return countFields(openConn, sepChar, quoteSet, nskip, RRuntime.fromLogical(blskip), comChar); + } catch (IllegalStateException | IOException ex) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, ex.getMessage()); + } + } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Crc64.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Crc64.java index cb75d43aba6a088af72b77b6d179039a34d67dc6..359da6fe970ccc439d4e31f208e402a5e6cd747b 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Crc64.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Crc64.java @@ -25,15 +25,15 @@ package com.oracle.truffle.r.library.utils; import java.security.*; 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.*; -public class Crc64 { - /** - * GnuR uses lzma, but unless we care about exact match (and the usage doesn't suggest we need - * to, we can use any algorithm that provides a unique-ish result. - */ +public abstract class Crc64 extends RExternalBuiltinNode.Arg1 { + @TruffleBoundary - public static String crc64(String input) { + @Specialization + protected String crc64(String input) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] digest = md.digest(input.getBytes()); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Download.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Download.java index affe5ed6e594d67a82cc04885a4d82fd1fe3c295..d49c612cc385e8c27bca5c0f70753dfe92ac95a8 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Download.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Download.java @@ -25,13 +25,18 @@ package com.oracle.truffle.r.library.utils; import java.io.*; import java.net.*; +import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.r.runtime.*; +import com.oracle.truffle.r.runtime.data.*; + /** * Support for the "internal"method of "utils::download.file". TODO take note of "quiet", "mode" and * "cacheOK". */ -public class Download { +public final class Download extends RExternalBuiltinNode { + @SuppressWarnings("unused") - public static void download(String urlString, String destFile, boolean quiet, String mode, boolean cacheOK) throws IOException { + private static void download(String urlString, String destFile, boolean quiet, String mode, boolean cacheOK) throws IOException { URL url = new URL(urlString); byte[] buffer = new byte[8192]; try (BufferedInputStream in = new BufferedInputStream(url.openStream()); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(destFile))) { @@ -41,4 +46,25 @@ public class Download { } } } + + @Override + public Integer call(RArgsValuesAndNames args) { + Object[] argValues = args.getArguments(); + String url = isString(argValues[0]); + String destFile = isString(argValues[1]); + byte quiet = castLogical(castVector(argValues[2])); + String mode = isString(argValues[3]); + byte cacheOK = castLogical(castVector(argValues[4])); + if (url == null || destFile == null || mode == null) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_UNNAMED_ARGUMENTS); + } + try { + Download.download(url, destFile, RRuntime.fromLogical(quiet), mode, RRuntime.fromLogical(cacheOK)); + return 0; + } catch (IOException ex) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, ex.getMessage()); + } + } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Menu.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Menu.java index 1b07f13b516464b2c80f3b88b9f5fc853f4f24b9..dbf820d8c88d378bbb736fd8bd57ec5569fb0259 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Menu.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Menu.java @@ -11,15 +11,21 @@ */ package com.oracle.truffle.r.library.utils; +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.RContext.*; +import com.oracle.truffle.r.runtime.RContext.ConsoleHandler; +import com.oracle.truffle.r.runtime.data.model.*; // Translated from GnuR: library/utils/io.c -public class Menu { - public static int menu(String[] choices) { +public abstract class Menu extends RExternalBuiltinNode.Arg1 { + + @Specialization + protected int menu(RAbstractStringVector choices) { ConsoleHandler ch = RContext.getInstance().getConsoleHandler(); - int first = choices.length + 1; + int first = choices.getLength() + 1; ch.print("Selection: "); String response = ch.readLine().trim(); if (response.length() > 0) { @@ -30,8 +36,8 @@ public class Menu { // } } else { - for (int i = 0; i < choices.length; i++) { - String entry = choices[i]; + for (int i = 0; i < choices.getLength(); i++) { + String entry = choices.getDataAt(i); if (entry.equals(response)) { first = i + 1; break; @@ -41,4 +47,10 @@ public class Menu { } return first; } + + @Fallback + @TruffleBoundary + protected int menu(@SuppressWarnings("unused") Object choices) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "choices"); + } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java index 27b13c2c98dae9932eadb4a3e930a871461b7173..2b91e0137c13a902fee60509c7a7ac59049582c0 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java @@ -24,11 +24,13 @@ package com.oracle.truffle.r.library.utils; import java.util.*; +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.*; -public class TypeConvert { +public abstract class TypeConvert extends RExternalBuiltinNode.Arg5 { private static boolean isNA(String s, RAbstractStringVector naStrings) { for (int i = 0; i < naStrings.getLength(); i++) { @@ -72,7 +74,8 @@ public class TypeConvert { return RDataFactory.createLogicalVector(data, firstPos > 0 ? RDataFactory.INCOMPLETE_VECTOR : RDataFactory.COMPLETE_VECTOR); } - public static Object typeConvert(RAbstractStringVector x, RAbstractStringVector naStrings, byte asIs, @SuppressWarnings("unused") String numeral) { + @Specialization + protected Object typeConvert(RAbstractStringVector x, RAbstractStringVector naStrings, byte asIs, @SuppressWarnings("unused") Object dec, @SuppressWarnings("unused") Object numeral) { if (x.getLength() == 0) { return RDataFactory.createEmptyLogicalVector(); } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/WriteTable.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/WriteTable.java index 14dcbc50e404039f706f71fcdbcb328452eb4fd7..0709a0ec70df2f01497976f759e24984e0c92001 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/WriteTable.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/WriteTable.java @@ -14,6 +14,7 @@ package com.oracle.truffle.r.library.utils; import java.io.*; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.conn.*; import com.oracle.truffle.r.runtime.data.*; @@ -21,13 +22,11 @@ import com.oracle.truffle.r.runtime.data.model.*; //Transcribed from GnuR, library/utils/src/io.c -//Checkstyle: stop -public class WriteTable { - // @formatter:off +public final class WriteTable extends RExternalBuiltinNode { + @TruffleBoundary - public static Object execute(RConnection con, Object xx, int nr, int nc, Object rnames, String csep, String ceol, String cna, - char cdec, boolean qmethod, boolean[] quoteCol, boolean quoteRn) throws IOException, IllegalArgumentException { - // @formatter:on + private static Object execute(RConnection con, Object xx, int nr, int nc, Object rnames, String csep, String ceol, String cna, char cdec, boolean qmethod, boolean[] quoteCol, boolean quoteRn) + throws IOException, IllegalArgumentException { OutputStream os = con.getOutputStream(); String tmp = null; if (xx instanceof RDataFrame) { /* A data frame */ @@ -226,4 +225,87 @@ public class WriteTable { } return false; } + + private void invalidArgument(String name) throws RError { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, name); + } + + // Transcribed from GnuR, library/utils/src/io.c + @Override + public Object call(RArgsValuesAndNames args) { + Object[] argValues = args.getArguments(); + Object conArg = argValues[1]; + RConnection conn; + if (!(conArg instanceof RConnection)) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, "'file' is not a connection"); + } else { + conn = (RConnection) conArg; + } + // TODO check connection writeable + + int nr = castInt(castVector(argValues[2])); + int nc = castInt(castVector(argValues[3])); + Object rnamesArg = argValues[4]; + Object sepArg = argValues[5]; + Object eolArg = argValues[6]; + Object naArg = argValues[7]; + Object decArg = argValues[8]; + Object quoteArg = argValues[9]; + byte qmethod = castLogical(castVector(argValues[10])); + + String csep; + String ceol; + String cna; + String cdec; + + if (nr == RRuntime.INT_NA) { + invalidArgument("nr"); + } + if (nc == RRuntime.INT_NA) { + invalidArgument("nc"); + } + if (!(rnamesArg instanceof RNull) && isString(rnamesArg) == null) { + invalidArgument("rnames"); + } + if ((csep = isString(sepArg)) == null) { + invalidArgument("sep"); + } + if ((ceol = isString(eolArg)) == null) { + invalidArgument("eol"); + } + if ((cna = isString(naArg)) == null) { + invalidArgument("na"); + } + if ((cdec = isString(decArg)) == null) { + invalidArgument("dec"); + } + if (qmethod == RRuntime.LOGICAL_NA) { + invalidArgument("qmethod"); + } + if (cdec.length() != 1) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, "'dec' must be a single character"); + } + boolean[] quoteCol = new boolean[nc]; + boolean quoteRn = false; + RAbstractIntVector quote = (RAbstractIntVector) castVector(quoteArg); + for (int i = 0; i < quote.getLength(); i++) { + int qi = quote.getDataAt(i); + if (qi == 0) { + quoteRn = true; + } + if (qi > 0) { + quoteCol[qi - 1] = true; + } + } + try (RConnection openConn = conn.forceOpen("wt")) { + execute(openConn, argValues[0], nr, nc, rnamesArg, csep, ceol, cna, cdec.charAt(0), RRuntime.fromLogical(qmethod), quoteCol, quoteRn); + } catch (IOException | IllegalArgumentException ex) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, ex.getMessage()); + } + return RNull.instance; + } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java index d5c3a31d32f7b69d31894af1c0381410bab6284c..328873efa0fb4b516c2fd658f73fc5c5d8b5ad38 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java @@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.builtin.base; import com.oracle.truffle.r.nodes.binary.*; import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.r.nodes.builtin.base.foreign.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.ops.*; @@ -226,7 +227,7 @@ public class BasePackage extends RBuiltinPackage { add(FileFunctions.ListDirs.class, FileFunctionsFactory.ListDirsNodeGen::create); add(FileFunctions.Unlink.class, FileFunctionsFactory.UnlinkNodeGen::create); add(Floor.class, Floor::new); - add(ForeignFunctions.C.class, ForeignFunctionsFactory.CNodeGen::create); + add(DotC.class, DotCNodeGen::create); add(ForeignFunctions.DotCall.class, ForeignFunctionsFactory.DotCallNodeGen::create); add(ForeignFunctions.DotExternal.class, ForeignFunctionsFactory.DotExternalNodeGen::create); add(ForeignFunctions.DotExternal2.class, ForeignFunctionsFactory.DotExternal2NodeGen::create); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ForeignFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ForeignFunctions.java deleted file mode 100644 index b2477a039bbdd872e7376db58d03d8ea848f3667..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ForeignFunctions.java +++ /dev/null @@ -1,1095 +0,0 @@ -/* - * This material is distributed under the GNU General Public License - * Version 2. You may review the terms of this license at - * http://www.gnu.org/licenses/gpl-2.0.html - * - * Copyright (c) 1995-2012, The R Core Team - * Copyright (c) 2003, The R Foundation - * Copyright (c) 2015, Oracle and/or its affiliates - * - * All rights reserved. - */ -package com.oracle.truffle.r.nodes.builtin.base; - -import java.io.*; - -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.api.nodes.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.r.library.graphics.*; -import com.oracle.truffle.r.library.methods.*; -import com.oracle.truffle.r.library.stats.*; -import com.oracle.truffle.r.library.tools.*; -import com.oracle.truffle.r.library.utils.*; -import com.oracle.truffle.r.nodes.builtin.*; -import com.oracle.truffle.r.nodes.builtin.base.ForeignFunctionsFactory.DotExternal2NodeGen.ParseRdNodeGen; -import com.oracle.truffle.r.nodes.unary.*; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.RError.Message; -import com.oracle.truffle.r.runtime.conn.*; -import com.oracle.truffle.r.runtime.data.*; -import com.oracle.truffle.r.runtime.data.model.*; -import com.oracle.truffle.r.runtime.env.*; -import com.oracle.truffle.r.runtime.ffi.*; -import com.oracle.truffle.r.runtime.ffi.DLL.SymbolInfo; - -/** - * {@code .C}, {@code .Call} {@code .Fortran}, {@code .External}, {@code .External2}, - * {@code External.graphics} functions. - * - * TODO Completeness (more types, more error checks), Performance (copying). Especially all the - * subtleties around copying. - * - * See <a href="https://stat.ethz.ch/R-manual/R-devel/library/base/html/Foreign.html">here</a>. - */ -public class ForeignFunctions { - public abstract static class FortranCAdapter extends CastAdapter { - - protected final BranchProfile errorProfile = BranchProfile.create(); - - @Override - public Object[] getDefaultParameterValues() { - return new Object[]{RMissing.instance, RArgsValuesAndNames.EMPTY, RRuntime.LOGICAL_FALSE, RRuntime.LOGICAL_FALSE, RMissing.instance, RMissing.instance}; - } - - protected int[] checkNAs(int argIndex, int[] data) { - for (int i = 0; i < data.length; i++) { - if (RRuntime.isNA(data[i])) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.NA_IN_FOREIGN_FUNCTION_CALL, argIndex); - } - } - return data; - } - - protected double[] checkNAs(int argIndex, double[] data) { - for (int i = 0; i < data.length; i++) { - if (!RRuntime.isFinite(data[i])) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.NA_NAN_INF_IN_FOREIGN_FUNCTION_CALL, argIndex); - } - } - return data; - } - } - - /** - * For now, just some special case functions that are built in to the implementation. - */ - @RBuiltin(name = ".Fortran", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "NAOK", "DUP", "PACKAGE", "ENCODING"}) - public abstract static class Fortran extends FortranCAdapter { - private static final String E = RRuntime.NAMES_ATTR_EMPTY_VALUE; - private static final RStringVector DQRDC2_NAMES = RDataFactory.createStringVector(new String[]{"qr", E, E, E, E, "rank", "qraux", "pivot", E}, RDataFactory.COMPLETE_VECTOR); - - @SuppressWarnings("unused") - @Specialization(guards = "dqrdc2(f)") - protected RList fortranDqrdc2(RList f, RArgsValuesAndNames args, byte naok, byte dup, RMissing rPackage, RMissing encoding) { - controlVisibility(); - Object[] argValues = args.getArguments(); - try { - RAbstractDoubleVector xVec = (RAbstractDoubleVector) argValues[0]; - int ldx = (int) argValues[1]; - int n = (int) argValues[2]; - int p = (int) argValues[3]; - double tol = (double) argValues[4]; - RAbstractIntVector rankVec = (RAbstractIntVector) argValues[5]; - RAbstractDoubleVector qrauxVec = (RAbstractDoubleVector) argValues[6]; - RAbstractIntVector pivotVec = (RAbstractIntVector) argValues[7]; - RAbstractDoubleVector workVec = (RAbstractDoubleVector) argValues[8]; - double[] x = xVec.materialize().getDataTemp(); - int[] rank = rankVec.materialize().getDataTemp(); - double[] qraux = qrauxVec.materialize().getDataTemp(); - int[] pivot = pivotVec.materialize().getDataTemp(); - RFFIFactory.getRFFI().getRApplRFFI().dqrdc2(x, ldx, n, p, tol, rank, qraux, pivot, workVec.materialize().getDataCopy()); - // @formatter:off - Object[] data = new Object[]{ - RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR, xVec.getDimensions()), - argValues[1], argValues[2], argValues[3], argValues[4], - RDataFactory.createIntVector(rank, RDataFactory.COMPLETE_VECTOR), - RDataFactory.createDoubleVector(qraux, RDataFactory.COMPLETE_VECTOR), - RDataFactory.createIntVector(pivot, RDataFactory.COMPLETE_VECTOR), - argValues[8] - }; - // @formatter:on - return RDataFactory.createList(data, DQRDC2_NAMES); - } catch (ClassCastException | ArrayIndexOutOfBoundsException ex) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INCORRECT_ARG, "dqrdc2"); - } - } - - public boolean dqrdc2(RList f) { - return matchName(f, "dqrdc2"); - } - - private static final RStringVector DQRCF_NAMES = RDataFactory.createStringVector(new String[]{E, E, E, E, E, E, "coef", "info"}, RDataFactory.COMPLETE_VECTOR); - - @SuppressWarnings("unused") - @Specialization(guards = "dqrcf(f)") - protected RList fortranDqrcf(RList f, RArgsValuesAndNames args, byte naok, byte dup, RMissing rPackage, RMissing encoding) { - controlVisibility(); - Object[] argValues = args.getArguments(); - try { - RAbstractDoubleVector xVec = (RAbstractDoubleVector) argValues[0]; - int n = (int) argValues[1]; - RAbstractIntVector k = (RAbstractIntVector) argValues[2]; - RAbstractDoubleVector qrauxVec = (RAbstractDoubleVector) argValues[3]; - RAbstractDoubleVector yVec = (RAbstractDoubleVector) argValues[4]; - int ny = (int) argValues[5]; - RAbstractDoubleVector bVec = (RAbstractDoubleVector) argValues[6]; - RAbstractIntVector infoVec = (RAbstractIntVector) argValues[7]; - double[] x = xVec.materialize().getDataTemp(); - double[] qraux = qrauxVec.materialize().getDataTemp(); - double[] y = yVec.materialize().getDataTemp(); - double[] b = bVec.materialize().getDataTemp(); - int[] info = infoVec.materialize().getDataTemp(); - RFFIFactory.getRFFI().getRApplRFFI().dqrcf(x, n, k.getDataAt(0), qraux, y, ny, b, info); - RDoubleVector coef = RDataFactory.createDoubleVector(b, RDataFactory.COMPLETE_VECTOR); - coef.copyAttributesFrom(attrProfiles, bVec); - // @formatter:off - Object[] data = new Object[]{ - RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR), - argValues[1], - k.copy(), - RDataFactory.createDoubleVector(qraux, RDataFactory.COMPLETE_VECTOR), - RDataFactory.createDoubleVector(y, RDataFactory.COMPLETE_VECTOR), - argValues[5], - coef, - RDataFactory.createIntVector(info, RDataFactory.COMPLETE_VECTOR), - }; - // @formatter:on - return RDataFactory.createList(data, DQRCF_NAMES); - - } catch (ClassCastException | ArrayIndexOutOfBoundsException ex) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INCORRECT_ARG, "dqrcf"); - } - } - - public boolean dqrcf(RList f) { - return matchName(f, "dqrcf"); - } - - } - - @RBuiltin(name = ".C", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "NAOK", "DUP", "PACKAGE", "ENCODING"}) - public abstract static class C extends FortranCAdapter { - - private static final int SCALAR_DOUBLE = 0; - private static final int SCALAR_INT = 1; - private static final int SCALAR_LOGICAL = 2; - @SuppressWarnings("unused") private static final int SCALAR_STRING = 3; - private static final int VECTOR_DOUBLE = 10; - private static final int VECTOR_INT = 11; - private static final int VECTOR_LOGICAL = 12; - @SuppressWarnings("unused") private static final int VECTOR_STRING = 12; - - @SuppressWarnings("unused") - @Specialization - protected RList c(String f, RArgsValuesAndNames args, byte naok, byte dup, RMissing rPackage, RMissing encoding) { - controlVisibility(); - Object[] argValues = args.getArguments(); - SymbolInfo symbolInfo = DLL.findSymbolInfo(f, null); - if (symbolInfo == null) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.C_SYMBOL_NOT_IN_TABLE, f); - } - boolean dupArgs = RRuntime.fromLogical(dup); - boolean checkNA = RRuntime.fromLogical(naok); - // Analyze the args, making copies (ignoring dup for now) - int[] argTypes = new int[argValues.length]; - Object[] nativeArgs = new Object[argValues.length]; - for (int i = 0; i < argValues.length; i++) { - Object arg = argValues[i]; - if (arg instanceof RAbstractDoubleVector) { - argTypes[i] = VECTOR_DOUBLE; - nativeArgs[i] = checkNAs(i + 1, ((RAbstractDoubleVector) arg).materialize().getDataCopy()); - } else if (arg instanceof RAbstractIntVector) { - argTypes[i] = VECTOR_INT; - nativeArgs[i] = checkNAs(i + 1, ((RAbstractIntVector) arg).materialize().getDataCopy()); - } else if (arg instanceof RAbstractLogicalVector) { - argTypes[i] = VECTOR_LOGICAL; - // passed as int[] - byte[] data = ((RAbstractLogicalVector) arg).materialize().getDataWithoutCopying(); - int[] dataAsInt = new int[data.length]; - for (int j = 0; j < data.length; j++) { - // An NA is an error but the error handling happens in checkNAs - dataAsInt[j] = RRuntime.isNA(data[j]) ? RRuntime.INT_NA : data[j]; - } - nativeArgs[i] = checkNAs(i + 1, dataAsInt); - } else if (arg instanceof Double) { - argTypes[i] = SCALAR_DOUBLE; - nativeArgs[i] = checkNAs(i + 1, new double[]{(double) arg}); - } else if (arg instanceof Integer) { - argTypes[i] = SCALAR_INT; - nativeArgs[i] = checkNAs(i + 1, new int[]{(int) arg}); - } else if (arg instanceof Byte) { - argTypes[i] = SCALAR_LOGICAL; - nativeArgs[i] = checkNAs(i + 1, new int[]{RRuntime.isNA((byte) arg) ? RRuntime.INT_NA : (byte) arg}); - } else { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNIMPLEMENTED_ARG_TYPE, i + 1); - } - } - try { - RFFIFactory.getRFFI().getCRFFI().invoke(symbolInfo, nativeArgs); - } catch (Throwable t) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.NATIVE_CALL_FAILED, t.getMessage()); - } - // we have to assume that the native method updated everything - RStringVector listNames = validateArgNames(argValues.length, getSuppliedSignature()); - Object[] results = new Object[argValues.length]; - for (int i = 0; i < argValues.length; i++) { - switch (argTypes[i]) { - case SCALAR_DOUBLE: - results[i] = RDataFactory.createDoubleVector((double[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); - break; - case SCALAR_INT: - results[i] = RDataFactory.createIntVector((int[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); - break; - case SCALAR_LOGICAL: - results[i] = RDataFactory.createLogicalVector((byte[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); - break; - case VECTOR_DOUBLE: { - results[i] = ((RAbstractDoubleVector) argValues[i]).materialize().copyResetData((double[]) nativeArgs[i]); - break; - } - case VECTOR_INT: { - results[i] = ((RAbstractIntVector) argValues[i]).materialize().copyResetData((int[]) nativeArgs[i]); - break; - } - case VECTOR_LOGICAL: { - results[i] = ((RAbstractLogicalVector) argValues[i]).materialize().copyResetData((byte[]) nativeArgs[i]); - break; - } - - } - } - return RDataFactory.createList(results, listNames); - } - - private static RStringVector validateArgNames(int argsLength, ArgumentsSignature signature) { - String[] listArgNames = new String[argsLength]; - for (int i = 0; i < argsLength; i++) { - String name = signature.getName(i + 1); - if (name == null) { - name = RRuntime.NAMES_ATTR_EMPTY_VALUE; - } - listArgNames[i] = name; - } - return RDataFactory.createStringVector(listArgNames, RDataFactory.COMPLETE_VECTOR); - } - - } - - /** - * Handles the generic case, but also many special case functions that are called from the - * default packages. - */ - @RBuiltin(name = ".Call", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}) - public abstract static class DotCall extends CastAdapter { - - private final BranchProfile errorProfile = BranchProfile.create(); - private final ConditionProfile zVecLgt1 = ConditionProfile.createBinaryProfile(); - private final ConditionProfile noDims = ConditionProfile.createBinaryProfile(); - - @Override - public Object[] getDefaultParameterValues() { - return new Object[]{RMissing.instance, RArgsValuesAndNames.EMPTY, RMissing.instance}; - } - - // TODO: handle more argument types (this is sufficient to run the b25 benchmarks) - @SuppressWarnings("unused") - @Specialization(guards = "fft(f)") - protected RComplexVector callFFT(RList f, RArgsValuesAndNames args, RMissing packageName) { - controlVisibility(); - Object[] argValues = args.getArguments(); - RComplexVector zVec = castComplexVector(castVector(argValues[0])); - double[] z = zVec.getDataTemp(); - byte inverse = castLogical(castVector(argValues[1])); - int inv = RRuntime.isNA(inverse) || inverse == RRuntime.LOGICAL_FALSE ? -2 : 2; - int retCode = 7; - if (zVecLgt1.profile(zVec.getLength() > 1)) { - int[] maxf = new int[1]; - int[] maxp = new int[1]; - if (noDims.profile(zVec.getDimensions() == null)) { - int n = zVec.getLength(); - RFFIFactory.getRFFI().getStatsRFFI().fft_factor(n, maxf, maxp); - if (maxf[0] == 0) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.FFT_FACTORIZATION); - } - double[] work = new double[4 * maxf[0]]; - int[] iwork = new int[maxp[0]]; - retCode = RFFIFactory.getRFFI().getStatsRFFI().fft_work(z, 1, n, 1, inv, work, iwork); - } else { - int maxmaxf = 1; - int maxmaxp = 1; - int[] d = zVec.getDimensions(); - int ndims = d.length; - /* do whole loop just for error checking and maxmax[fp] .. */ - for (int i = 0; i < ndims; i++) { - if (d[i] > 1) { - RFFIFactory.getRFFI().getStatsRFFI().fft_factor(d[i], maxf, maxp); - if (maxf[0] == 0) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.FFT_FACTORIZATION); - } - if (maxf[0] > maxmaxf) { - maxmaxf = maxf[0]; - } - if (maxp[0] > maxmaxp) { - maxmaxp = maxp[0]; - } - } - } - double[] work = new double[4 * maxmaxf]; - int[] iwork = new int[maxmaxp]; - int nseg = zVec.getLength(); - int n = 1; - int nspn = 1; - for (int i = 0; i < ndims; i++) { - if (d[i] > 1) { - nspn *= n; - n = d[i]; - nseg /= n; - RFFIFactory.getRFFI().getStatsRFFI().fft_factor(n, maxf, maxp); - RFFIFactory.getRFFI().getStatsRFFI().fft_work(z, nseg, n, nspn, inv, work, iwork); - } - } - - } - } - - return RDataFactory.createComplexVector(z, zVec.isComplete(), zVec.getDimensions()); - } - - public boolean fft(RList f) { - return matchName(f, "fft"); - } - - @SuppressWarnings("unused") - @Specialization(guards = "initMethodDispatch(f)") - @TruffleBoundary - protected REnvironment initMethodDispatch(RList f, RArgsValuesAndNames args, RMissing packageName) { - controlVisibility(); - Object[] argValues = args.getArguments(); - REnvironment env = (REnvironment) argValues[0]; - // TBD what should we actually do here - return MethodsListDispatch.getInstance().initMethodDispatch(env); - } - - public boolean initMethodDispatch(RList f) { - return matchName(f, "R_initMethodDispatch"); - } - - @SuppressWarnings("unused") - @TruffleBoundary - @Specialization(guards = "methodsPackageMetaName(f)") - protected String callMethodsPackageMetaName(RList f, RArgsValuesAndNames args, RMissing packageName) { - controlVisibility(); - Object[] argValues = args.getArguments(); - // TODO proper error checks - String prefixString = (String) argValues[0]; - String nameString = (String) argValues[1]; - String pkgString = (String) argValues[2]; - return MethodsListDispatch.getInstance().methodsPackageMetaName(prefixString, nameString, pkgString); - } - - public boolean methodsPackageMetaName(RList f) { - return matchName(f, "R_methodsPackageMetaName"); - } - - @SuppressWarnings("unused") - @Specialization(guards = "isSetPrimitiveMethods(f)") - @TruffleBoundary - protected Object setPrimitiveMethods(RList f, RArgsValuesAndNames args, RMissing packageName) { - controlVisibility(); - Object[] argValues = args.getArguments(); - // TODO proper error checks - String fname = RRuntime.asString(argValues[0]); - Object op = argValues[1]; - String codeVec = RRuntime.asString(argValues[2]); - RFunction fundef = (RFunction) argValues[3]; - Object mlist = argValues[4]; - return SetPrimitiveMethods.doit(fname, op, codeVec, fundef, mlist); - } - - public boolean isSetPrimitiveMethods(RList f) { - return matchName(f, "R_M_setPrimitiveMethods"); - } - - @SuppressWarnings("unused") - @TruffleBoundary - @Specialization(guards = "getClassFromCache(f)") - protected Object callGetClassFromCache(RList f, RArgsValuesAndNames args, RMissing packageName) { - controlVisibility(); - Object[] argValues = args.getArguments(); - REnvironment table = (REnvironment) argValues[1]; - String klassString = RRuntime.asString(argValues[0]); - if (klassString != null) { - return MethodsListDispatch.getInstance().getClassFromCache(table, klassString); - } else { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE); - } - } - - public boolean getClassFromCache(RList f) { - return matchName(f, "R_getClassFromCache"); - } - - @SuppressWarnings("unused") - @TruffleBoundary - @Specialization(guards = "setMethodDispatch(f)") - protected Object callSetMethodDispatch(RList f, RArgsValuesAndNames args, RMissing packageName) { - controlVisibility(); - byte onOff = (byte) args.getArgument(0); - return MethodsListDispatch.getInstance().setMethodDispatch(onOff); - } - - public boolean setMethodDispatch(RList f) { - return matchName(f, "R_set_method_dispatch"); - } - - @Specialization - public Object callNamedFunction(String name, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - return callNamedFunctionWithPackage(name, args, null); - } - - @Specialization - public Object callNamedFunctionWithPackage(String name, RArgsValuesAndNames args, String packageName) { - SymbolInfo symbolInfo = DLL.findSymbolInfo(name, packageName); - if (symbolInfo == null) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), Message.C_SYMBOL_NOT_IN_TABLE, name); - } - try { - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(symbolInfo, args.getArguments()); - } catch (Throwable t) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.NATIVE_CALL_FAILED, t.getMessage()); - } - } - - @SuppressWarnings("unused") - @Specialization(guards = "isFlushconsole(f)") - protected RNull flushConsole(RList f, RArgsValuesAndNames args, RMissing packageName) { - return RNull.instance; - } - - public boolean isFlushconsole(RList f) { - return matchName(f, "flushconsole"); - } - - @SuppressWarnings("unused") - @Specialization(guards = "isCrc64(f)") - protected String crc64(RList f, RArgsValuesAndNames args, RMissing packageName) { - String input = RRuntime.asString(args.getArgument(0)); - return Crc64.crc64(input); - } - - public boolean isCrc64(RList f) { - return matchName(f, "crc64"); - } - - @SuppressWarnings("unused") - @Specialization(guards = "isMenu(f)") - @TruffleBoundary - protected int menu(RList f, RArgsValuesAndNames args, RMissing packageName) { - Object[] values = args.getArguments(); - String[] choices; - if (values[0] instanceof String) { - choices = new String[]{(String) values[0]}; - } else if (values[0] instanceof RAbstractStringVector) { - choices = ((RAbstractStringVector) values[0]).materialize().getDataWithoutCopying(); - } else { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "choices"); - } - return Menu.menu(choices); - } - - public boolean isMenu(RList f) { - return matchName(f, "menu"); - } - - @SuppressWarnings("unused") - @Specialization(guards = "isCairoProps(f)") - protected byte cairoProps(RList f, RArgsValuesAndNames args, RMissing packageName) { - return RRuntime.LOGICAL_FALSE; - } - - public boolean isCairoProps(RList f) { - return matchName(f, "cairoProps"); - } - - @SuppressWarnings("unused") - @Specialization(guards = "isMakeQuartzDefault(f)") - protected byte makeQuartzDefault(RList f, RArgsValuesAndNames args, RMissing packageName) { - return RRuntime.LOGICAL_FALSE; - } - - public boolean isMakeQuartzDefault(RList f) { - return matchName(f, "makeQuartzDefault"); - } - - @Specialization(guards = "isCor(f)") - protected Object doCor(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - return doCovCor(false, args); - } - - public boolean isCor(RList f) { - return matchName(f, "cor"); - } - - @Specialization(guards = "isCov(f)") - protected Object doCov(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - return doCovCor(true, args); - } - - public boolean isCov(RList f) { - return matchName(f, "cov"); - } - - private Object doCovCor(boolean isCov, RArgsValuesAndNames args) { - controlVisibility(); - Object[] argValues = args.getArguments(); - if (argValues[0] == RNull.instance) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.IS_NULL, "x"); - } - // TODO error checks/coercions - RAbstractDoubleVector x = (RAbstractDoubleVector) argValues[0]; - RAbstractDoubleVector y = argValues[1] == RNull.instance ? null : (RAbstractDoubleVector) argValues[1]; - int method = ((RAbstractIntVector) argValues[2]).getDataAt(0); - if (method != 4) { - throw RError.nyi(getEncapsulatingSourceSection(), "method"); - } - boolean iskendall = RRuntime.fromLogical(castLogical(castVector(argValues[3]))); - return Covcor.getInstance().corcov(x.materialize(), y != null ? y.materialize() : null, method, iskendall, !isCov, getEncapsulatingSourceSection()); - - } - - @Specialization(guards = "isSplineCoef(f)") - protected RList splineCoef(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - int method = castInt(castVector(args.getArguments()[0])); - RAbstractDoubleVector x = (RAbstractDoubleVector) castVector(args.getArguments()[1]); - RAbstractDoubleVector y = (RAbstractDoubleVector) castVector(args.getArguments()[2]); - return SplineFunctions.splineCoef(method, x.materialize(), y.materialize()); - } - - public boolean isSplineCoef(RList f) { - return matchName(f, "SplineCoef"); - } - - @Specialization(guards = "isSplineEval(f)") - protected RDoubleVector splineEval(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - RAbstractDoubleVector xout = (RAbstractDoubleVector) castVector(args.getArgument(0)); - // This is called with the result of SplineCoef, so it is surely an RList - return SplineFunctions.splineEval(attrProfiles, xout.materialize(), (RList) args.getArgument(1)); - } - - public boolean isSplineEval(RList f) { - return matchName(f, "SplineEval"); - } - - @Specialization(guards = "isDoTabExpand(f)") - protected RStringVector tabExpand(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - RAbstractStringVector strings = (RAbstractStringVector) castVector(args.getArgument(0)); - RAbstractIntVector starts = (RAbstractIntVector) castVector(args.getArgument(1)); - return ToolsText.doTabExpand(strings.materialize(), starts.materialize()); - } - - public boolean isDoTabExpand(RList f) { - return matchName(f, "doTabExpand"); - } - - @Specialization(guards = "isCodeFilesAppend(f)") - protected RLogicalVector codeFilesAppend(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - RStringVector file1 = (RStringVector) castVector(args.getArgument(0)); - RStringVector file2 = (RStringVector) castVector(args.getArgument(1)); - if (file1.getLength() != 1) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "file1"); - } - if (file2.getLength() < 1) { - return RDataFactory.createEmptyLogicalVector(); - } - return ToolsText.filesAppendLF(file1.getDataAt(0), file2); - } - - public boolean isCodeFilesAppend(RList f) { - return matchName(f, "codeFilesAppend"); - } - - @Specialization(guards = "isRmd5(f)") - protected RStringVector rmd5(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - RStringVector files = (RStringVector) castVector(args.getArgument(0)); - return ToolsRmd5.rmd5(files); - } - - public boolean isRmd5(RList f) { - return matchName(f, "Rmd5"); - } - - @Specialization(guards = "isDirChmod(f)") - protected RNull dirChmod(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - RAbstractVector dir = castVector(args.getArgument(0)); - if (!(dir instanceof RStringVector && ((RStringVector) dir).getLength() == 1)) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "dir"); - } - byte gws = castLogical(castVector(args.getArgument(1))); - ToolsDirChmod.dirChmod(((RStringVector) dir).getDataAt(0), RRuntime.fromLogical(gws)); - return RNull.instance; - } - - public boolean isDirChmod(RList f) { - return matchName(f, "dirchmod"); - } - - @SuppressWarnings("unused") - @Fallback - protected Object dotCallFallback(Object fobj, Object args, Object packageName) { - String name = null; - if (fobj instanceof RList) { - RList f = (RList) fobj; - RStringVector names = f.getNames(attrProfiles); - for (int i = 0; i < names.getLength(); i++) { - if (names.getDataAt(i).equals("name")) { - name = (String) f.getDataAt(i); - break; - } - } - } - throw new RInternalError(".Call specialization failure: %s ", name == null ? "<unknown>" : name); - } - - } - - private static String isString(Object arg) { - if (arg instanceof String) { - return (String) arg; - } else if (arg instanceof RAbstractStringVector) { - if (((RAbstractStringVector) arg).getLength() == 0) { - return null; - } else { - return ((RAbstractStringVector) arg).getDataAt(0); - } - } else { - return null; - } - } - - /** - * Casts for use on value elements of {@link RArgsValuesAndNames}. Since the starting value - * could a scalar, first use {@link #castVector}. - */ - protected abstract static class CastAdapter extends RBuiltinNode { - @Child private CastLogicalNode castLogical; - @Child private CastIntegerNode castInt; - @Child private CastDoubleNode castDouble; - @Child private CastComplexNode castComplex; - @Child private CastToVectorNode castVector; - - protected final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - - protected byte castLogical(RAbstractVector operand) { - if (castLogical == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castLogical = insert(CastLogicalNodeGen.create(null, false, false, false)); - } - return ((RAbstractLogicalVector) castLogical.executeCast(operand)).getDataAt(0); - } - - protected int castInt(RAbstractVector operand) { - if (castInt == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castInt = insert(CastIntegerNodeGen.create(null, false, false, false)); - } - return ((RAbstractIntVector) castInt.executeCast(operand)).getDataAt(0); - } - - protected RAbstractDoubleVector castDouble(RAbstractVector operand) { - if (castDouble == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castDouble = insert(CastDoubleNodeGen.create(null, false, false, false)); - } - return (RAbstractDoubleVector) castDouble.executeCast(operand); - } - - protected RComplexVector castComplexVector(Object operand) { - if (castComplex == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castComplex = insert(CastComplexNodeGen.create(null, true, true, false)); - } - return (RComplexVector) castComplex.executeCast(operand); - } - - protected RAbstractVector castVector(Object value) { - if (castVector == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castVector = insert(CastToVectorNodeGen.create(null, false, false, false, false)); - } - return (RAbstractVector) castVector.executeObject(value); - } - - /** - * This is an inefficient guard but it matters little unless there are many different calls - * being made within the same evaluation. A {@code NativeSymbolInfo} object would provide a - * more efficient basis. - */ - protected boolean matchName(RList f, String name) { - if (f.getNames(attrProfiles) == null) { - return false; - } - RAbstractStringVector names = f.getNames(attrProfiles); - for (int i = 0; i < names.getLength(); i++) { - if (names.getDataAt(i).equals("name")) { - return f.getDataAt(i).equals(name) ? true : false; - } - } - return false; - } - - } - - @RBuiltin(name = ".External", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}) - public abstract static class DotExternal extends CastAdapter { - - private final BranchProfile errorProfile = BranchProfile.create(); - - // Transcribed from GnuR, library/utils/src/io.c - @SuppressWarnings("unused") - @Specialization(guards = "isCountFields(f)") - protected Object countFields(RList f, RArgsValuesAndNames args, RMissing packageName) { - controlVisibility(); - Object[] argValues = args.getArguments(); - RConnection conn = (RConnection) argValues[0]; - Object sepArg = argValues[1]; - char sepChar; - Object quoteArg = argValues[2]; - int nskip = castInt(castVector(argValues[3])); - byte blskip = castLogical(castVector(argValues[4])); - String commentCharArg = isString(argValues[5]); - char comChar; - if (!(commentCharArg != null && commentCharArg.length() == 1)) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "comment.char"); - } else { - comChar = commentCharArg.charAt(0); - } - - if (nskip < 0 || nskip == RRuntime.INT_NA) { - nskip = 0; - } - if (blskip == RRuntime.LOGICAL_NA) { - blskip = RRuntime.LOGICAL_TRUE; - } - - if (sepArg instanceof RNull) { - sepChar = 0; - } else { - String s = isString(sepArg); - if (s == null) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "sep"); - } else { - if (s.length() == 0) { - sepChar = 0; - } else { - sepChar = s.charAt(0); - } - } - } - String quoteSet; - if (quoteArg instanceof RNull) { - quoteSet = ""; - } else { - String s = isString(quoteArg); - if (s == null) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, "invalid quote symbol set"); - } else { - quoteSet = s; - } - } - try (RConnection openConn = conn.forceOpen("r")) { - return CountFields.execute(openConn, sepChar, quoteSet, nskip, RRuntime.fromLogical(blskip), comChar); - } catch (IllegalStateException | IOException ex) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, ex.getMessage()); - } - } - - public boolean isCountFields(RList f) { - return matchName(f, "countfields"); - } - - @Specialization(guards = "isReadTableHead(f)") - protected Object doReadTableHead(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - // TODO This is quite incomplete and just uses readLines, which works for some inputs - controlVisibility(); - Object[] argValues = args.getArguments(); - RConnection conn = (RConnection) argValues[0]; - int nlines = castInt(castVector(argValues[1])); - try (RConnection openConn = conn.forceOpen("r")) { - return RDataFactory.createStringVector(openConn.readLines(nlines), RDataFactory.COMPLETE_VECTOR); - } catch (IOException ex) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.ERROR_READING_CONNECTION, ex.getMessage()); - } - } - - public boolean isReadTableHead(RList f) { - return matchName(f, "readtablehead"); - } - - @Specialization(guards = "isRnorm(f)") - protected Object doRnorm(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - controlVisibility(); - Object[] argValues = args.getArguments(); - int n = castInt(castVector(argValues[0])); - // TODO full error checks - double mean = (double) argValues[1]; - double standardd = (double) argValues[2]; - return Random2.rnorm(n, mean, standardd); - } - - public boolean isRnorm(RList f) { - return matchName(f, "rnorm"); - } - - @Specialization(guards = "isRunif(f)") - protected Object doRunif(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - controlVisibility(); - Object[] argValues = args.getArguments(); - // TODO full error checks - int n = castInt(castVector(argValues[0])); - double min = (castDouble(castVector(argValues[1]))).getDataAt(0); - double max = (castDouble(castVector(argValues[2]))).getDataAt(0); - return Runif.runif(n, min, max); - } - - public boolean isRunif(RList f) { - return matchName(f, "runif"); - } - - @Specialization(guards = "isQgamma(f)") - protected RAbstractDoubleVector doQgamma(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - controlVisibility(); - Object[] argValues = args.getArguments(); - RAbstractDoubleVector p = (RAbstractDoubleVector) castVector(argValues[0]); - RAbstractDoubleVector shape = (RAbstractDoubleVector) castVector(argValues[1]); - RAbstractDoubleVector scale = (RAbstractDoubleVector) castVector(argValues[2]); - if (shape.getLength() == 0 || scale.getLength() == 0) { - return RDataFactory.createEmptyDoubleVector(); - } - byte lowerTail = castLogical(castVector(argValues[3])); - byte logP = castLogical(castVector(argValues[4])); - return GammaFunctions.Qgamma.getInstance().qgamma(p, shape, scale, lowerTail, logP, attrProfiles); - } - - public boolean isQgamma(RList f) { - return matchName(f, "qgamma"); - } - - @Specialization(guards = "isDownload(f)") - protected int doDownload(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - controlVisibility(); - Object[] argValues = args.getArguments(); - String url = isString(argValues[0]); - String destFile = isString(argValues[1]); - byte quiet = castLogical(castVector(argValues[2])); - String mode = isString(argValues[3]); - byte cacheOK = castLogical(castVector(argValues[4])); - if (url == null || destFile == null || mode == null) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_UNNAMED_ARGUMENTS); - } - try { - Download.download(url, destFile, RRuntime.fromLogical(quiet), mode, RRuntime.fromLogical(cacheOK)); - return 0; - } catch (IOException ex) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, ex.getMessage()); - } - } - - public boolean isDownload(RList f) { - return matchName(f, "download"); - } - - } - - /* - * Fully qualified class necessary otherwise javac cannot find the symbol, related to nested - * ParseRd class. - */ - - @com.oracle.truffle.r.runtime.RBuiltin(name = ".External2", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "..."}) - public abstract static class DotExternal2 extends CastAdapter { - - private final BranchProfile errorProfile = BranchProfile.create(); - - // Transcribed from GnuR, library/utils/src/io.c - @Specialization(guards = "isWriteTable(f)") - protected Object doWriteTable(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args) { - controlVisibility(); - Object[] argValues = args.getArguments(); - Object conArg = argValues[1]; - RConnection conn; - if (!(conArg instanceof RConnection)) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, "'file' is not a connection"); - } else { - conn = (RConnection) conArg; - } - // TODO check connection writeable - - int nr = castInt(castVector(argValues[2])); - int nc = castInt(castVector(argValues[3])); - Object rnamesArg = argValues[4]; - Object sepArg = argValues[5]; - Object eolArg = argValues[6]; - Object naArg = argValues[7]; - Object decArg = argValues[8]; - Object quoteArg = argValues[9]; - byte qmethod = castLogical(castVector(argValues[10])); - - String csep; - String ceol; - String cna; - String cdec; - - if (nr == RRuntime.INT_NA) { - invalidArgument("nr"); - } - if (nc == RRuntime.INT_NA) { - invalidArgument("nc"); - } - if (!(rnamesArg instanceof RNull) && isString(rnamesArg) == null) { - invalidArgument("rnames"); - } - if ((csep = isString(sepArg)) == null) { - invalidArgument("sep"); - } - if ((ceol = isString(eolArg)) == null) { - invalidArgument("eol"); - } - if ((cna = isString(naArg)) == null) { - invalidArgument("na"); - } - if ((cdec = isString(decArg)) == null) { - invalidArgument("dec"); - } - if (qmethod == RRuntime.LOGICAL_NA) { - invalidArgument("qmethod"); - } - if (cdec.length() != 1) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, "'dec' must be a single character"); - } - boolean[] quoteCol = new boolean[nc]; - boolean quoteRn = false; - RAbstractIntVector quote = (RAbstractIntVector) castVector(quoteArg); - for (int i = 0; i < quote.getLength(); i++) { - int qi = quote.getDataAt(i); - if (qi == 0) { - quoteRn = true; - } - if (qi > 0) { - quoteCol[qi - 1] = true; - } - } - try (RConnection openConn = conn.forceOpen("wt")) { - WriteTable.execute(openConn, argValues[0], nr, nc, rnamesArg, csep, ceol, cna, cdec.charAt(0), RRuntime.fromLogical(qmethod), quoteCol, quoteRn); - } catch (IOException | IllegalArgumentException ex) { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.GENERIC, ex.getMessage()); - } - return RNull.instance; - } - - protected void invalidArgument(String name) throws RError { - errorProfile.enter(); - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, name); - } - - public boolean isWriteTable(RList f) { - return matchName(f, "writetable"); - } - - @TruffleBoundary - @Specialization(guards = "isTypeConvert(f)") - protected Object doTypeConvert(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args) { - controlVisibility(); - Object[] argValues = args.getArguments(); - RAbstractStringVector x = (RAbstractStringVector) argValues[0]; - RAbstractStringVector naStrings = (RAbstractStringVector) argValues[1]; - byte asIs = (byte) argValues[2]; - String numeral = RRuntime.asString(argValues[3]); - return TypeConvert.typeConvert(x, naStrings, asIs, numeral); - } - - public boolean isTypeConvert(RList f) { - return matchName(f, "typeconvert"); - } - - @TruffleBoundary - @Specialization(guards = "isPar(f)") - protected Object doPar(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args) { - controlVisibility(); - return GraphicsCCalls.par(args); - } - - public boolean isPar(RList f) { - return matchName(f, "C_par"); - } - - @Child ParseRdNode parseRdNode; - - @Specialization(guards = "isParseRd(f)") - protected Object parseRd(VirtualFrame frame, @SuppressWarnings("unused") RList f, RArgsValuesAndNames args) { - if (parseRdNode == null) { - parseRdNode = insert(ParseRdNodeGen.create()); - } - Object[] av = args.getArguments(); - return parseRdNode.execute(frame, av[0], av[1], av[2], av[3], av[4], av[5], av[6]); - } - - public abstract static class ParseRdNode extends Node { - public abstract Object execute(VirtualFrame frame, Object con, Object srcfile, Object encoding, Object verbose, Object basename, Object fragment, Object warningCalls); - - @Specialization - protected Object parseRd(RConnection con, REnvironment srcfile, String encoding, byte verbose, RAbstractStringVector basename, byte fragment, byte warningCalls) { - return ToolsParseRd.parseRd(con, srcfile, encoding, RRuntime.fromLogical(verbose), basename, RRuntime.fromLogical(fragment), RRuntime.fromLogical(warningCalls)); - } - - @SuppressWarnings("unused") - @Fallback - public Object parseRd(VirtualFrame frame, Object con, Object srcfile, Object encoding, Object verbose, Object basename, Object fragment, Object warningCalls) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS); - } - - } - - public boolean isParseRd(RList f) { - return matchName(f, "C_parseRd"); - } - } - - @RBuiltin(name = ".External.graphics", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "..."}) - public abstract static class DotExternalGraphics extends CastAdapter { - @TruffleBoundary - @Specialization(guards = "isPlotXY(f)") - protected RNull doPlotXY(@SuppressWarnings("unused") RList f, RArgsValuesAndNames args) { - controlVisibility(); - GraphicsCCalls.plotXy(((RAbstractDoubleVector) args.getArgument(0)).materialize()); - return RNull.instance; - } - - public boolean isPlotXY(RList f) { - return matchName(f, "C_plotXY"); - } - - } - -} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CairoProps.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CairoProps.java new file mode 100644 index 0000000000000000000000000000000000000000..3473c735832a70b4e3102e65e5a29fb7a75c3b22 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CairoProps.java @@ -0,0 +1,25 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995-2012, The R Core Team + * Copyright (c) 2003, The R Foundation + * Copyright (c) 2015, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.nodes.builtin.base.foreign; + +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.model.*; + +public abstract class CairoProps extends RExternalBuiltinNode.Arg1 { + + @Specialization + protected byte cairoProps(@SuppressWarnings("unused") RAbstractIntVector param) { + return RRuntime.LOGICAL_FALSE; + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java new file mode 100644 index 0000000000000000000000000000000000000000..9eebca4455a2026f9734a193acbb013f421e2711 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java @@ -0,0 +1,166 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995-2012, The R Core Team + * Copyright (c) 2003, The R Foundation + * Copyright (c) 2015, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.nodes.builtin.base.foreign; + +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.*; +import com.oracle.truffle.r.runtime.data.model.*; +import com.oracle.truffle.r.runtime.ffi.*; +import com.oracle.truffle.r.runtime.ffi.DLL.*; + +/** + * {@code .C} functions. + * + * TODO Completeness (more types, more error checks), Performance (copying). Especially all the + * subtleties around copying. + * + * See <a href="https://stat.ethz.ch/R-manual/R-devel/library/base/html/Foreign.html">here</a>. + */ +@RBuiltin(name = ".C", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "NAOK", "DUP", "PACKAGE", "ENCODING"}) +public abstract class DotC extends RBuiltinNode { + + private static final int SCALAR_DOUBLE = 0; + private static final int SCALAR_INT = 1; + private static final int SCALAR_LOGICAL = 2; + @SuppressWarnings("unused") private static final int SCALAR_STRING = 3; + private static final int VECTOR_DOUBLE = 10; + private static final int VECTOR_INT = 11; + private static final int VECTOR_LOGICAL = 12; + @SuppressWarnings("unused") private static final int VECTOR_STRING = 12; + + private final BranchProfile errorProfile = BranchProfile.create(); + + @Override + public Object[] getDefaultParameterValues() { + return new Object[]{RMissing.instance, RArgsValuesAndNames.EMPTY, RRuntime.LOGICAL_FALSE, RRuntime.LOGICAL_FALSE, RMissing.instance, RMissing.instance}; + } + + private int[] checkNAs(int argIndex, int[] data) { + for (int i = 0; i < data.length; i++) { + if (RRuntime.isNA(data[i])) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NA_IN_FOREIGN_FUNCTION_CALL, argIndex); + } + } + return data; + } + + private double[] checkNAs(int argIndex, double[] data) { + for (int i = 0; i < data.length; i++) { + if (!RRuntime.isFinite(data[i])) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NA_NAN_INF_IN_FOREIGN_FUNCTION_CALL, argIndex); + } + } + return data; + } + + private static RStringVector validateArgNames(int argsLength, ArgumentsSignature signature) { + String[] listArgNames = new String[argsLength]; + for (int i = 0; i < argsLength; i++) { + String name = signature.getName(i + 1); + if (name == null) { + name = RRuntime.NAMES_ATTR_EMPTY_VALUE; + } + listArgNames[i] = name; + } + return RDataFactory.createStringVector(listArgNames, RDataFactory.COMPLETE_VECTOR); + } + + @SuppressWarnings("unused") + @Specialization + protected RList c(String f, RArgsValuesAndNames args, byte naok, byte dup, RMissing rPackage, RMissing encoding) { + controlVisibility(); + Object[] argValues = args.getArguments(); + SymbolInfo symbolInfo = DLL.findSymbolInfo(f, null); + if (symbolInfo == null) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.C_SYMBOL_NOT_IN_TABLE, f); + } + boolean dupArgs = RRuntime.fromLogical(dup); + boolean checkNA = RRuntime.fromLogical(naok); + // Analyze the args, making copies (ignoring dup for now) + int[] argTypes = new int[argValues.length]; + Object[] nativeArgs = new Object[argValues.length]; + for (int i = 0; i < argValues.length; i++) { + Object arg = argValues[i]; + if (arg instanceof RAbstractDoubleVector) { + argTypes[i] = VECTOR_DOUBLE; + nativeArgs[i] = checkNAs(i + 1, ((RAbstractDoubleVector) arg).materialize().getDataCopy()); + } else if (arg instanceof RAbstractIntVector) { + argTypes[i] = VECTOR_INT; + nativeArgs[i] = checkNAs(i + 1, ((RAbstractIntVector) arg).materialize().getDataCopy()); + } else if (arg instanceof RAbstractLogicalVector) { + argTypes[i] = VECTOR_LOGICAL; + // passed as int[] + byte[] data = ((RAbstractLogicalVector) arg).materialize().getDataWithoutCopying(); + int[] dataAsInt = new int[data.length]; + for (int j = 0; j < data.length; j++) { + // An NA is an error but the error handling happens in checkNAs + dataAsInt[j] = RRuntime.isNA(data[j]) ? RRuntime.INT_NA : data[j]; + } + nativeArgs[i] = checkNAs(i + 1, dataAsInt); + } else if (arg instanceof Double) { + argTypes[i] = SCALAR_DOUBLE; + nativeArgs[i] = checkNAs(i + 1, new double[]{(double) arg}); + } else if (arg instanceof Integer) { + argTypes[i] = SCALAR_INT; + nativeArgs[i] = checkNAs(i + 1, new int[]{(int) arg}); + } else if (arg instanceof Byte) { + argTypes[i] = SCALAR_LOGICAL; + nativeArgs[i] = checkNAs(i + 1, new int[]{RRuntime.isNA((byte) arg) ? RRuntime.INT_NA : (byte) arg}); + } else { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNIMPLEMENTED_ARG_TYPE, i + 1); + } + } + try { + RFFIFactory.getRFFI().getCRFFI().invoke(symbolInfo, nativeArgs); + } catch (Throwable t) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NATIVE_CALL_FAILED, t.getMessage()); + } + // we have to assume that the native method updated everything + RStringVector listNames = validateArgNames(argValues.length, getSuppliedSignature()); + Object[] results = new Object[argValues.length]; + for (int i = 0; i < argValues.length; i++) { + switch (argTypes[i]) { + case SCALAR_DOUBLE: + results[i] = RDataFactory.createDoubleVector((double[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); + break; + case SCALAR_INT: + results[i] = RDataFactory.createIntVector((int[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); + break; + case SCALAR_LOGICAL: + results[i] = RDataFactory.createLogicalVector((byte[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); + break; + case VECTOR_DOUBLE: { + results[i] = ((RAbstractDoubleVector) argValues[i]).materialize().copyResetData((double[]) nativeArgs[i]); + break; + } + case VECTOR_INT: { + results[i] = ((RAbstractIntVector) argValues[i]).materialize().copyResetData((int[]) nativeArgs[i]); + break; + } + case VECTOR_LOGICAL: { + results[i] = ((RAbstractLogicalVector) argValues[i]).materialize().copyResetData((byte[]) nativeArgs[i]); + break; + } + + } + } + return RDataFactory.createList(results, listNames); + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java new file mode 100644 index 0000000000000000000000000000000000000000..7611b31a354a962b81ef0be3a95fe9bcc7fcf01a --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java @@ -0,0 +1,64 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995-2012, The R Core Team + * Copyright (c) 2003, The R Foundation + * Copyright (c) 2015, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.nodes.builtin.base.foreign; + +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 final class Dqrcf extends RExternalBuiltinNode { + + private static final String E = RRuntime.NAMES_ATTR_EMPTY_VALUE; + private static final RStringVector DQRCF_NAMES = RDataFactory.createStringVector(new String[]{E, E, E, E, E, E, "coef", "info"}, RDataFactory.COMPLETE_VECTOR); + + @Override + public RList call(RArgsValuesAndNames args) { + Object[] argValues = args.getArguments(); + try { + RAbstractDoubleVector xVec = (RAbstractDoubleVector) argValues[0]; + int n = (int) argValues[1]; + RAbstractIntVector k = (RAbstractIntVector) argValues[2]; + RAbstractDoubleVector qrauxVec = (RAbstractDoubleVector) argValues[3]; + RAbstractDoubleVector yVec = (RAbstractDoubleVector) argValues[4]; + int ny = (int) argValues[5]; + RAbstractDoubleVector bVec = (RAbstractDoubleVector) argValues[6]; + RAbstractIntVector infoVec = (RAbstractIntVector) argValues[7]; + double[] x = xVec.materialize().getDataTemp(); + double[] qraux = qrauxVec.materialize().getDataTemp(); + double[] y = yVec.materialize().getDataTemp(); + double[] b = bVec.materialize().getDataTemp(); + int[] info = infoVec.materialize().getDataTemp(); + RFFIFactory.getRFFI().getRApplRFFI().dqrcf(x, n, k.getDataAt(0), qraux, y, ny, b, info); + RDoubleVector coef = RDataFactory.createDoubleVector(b, RDataFactory.COMPLETE_VECTOR); + coef.copyAttributesFrom(attrProfiles, bVec); + // @formatter:off + Object[] data = new Object[]{ + RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR), + argValues[1], + k.copy(), + RDataFactory.createDoubleVector(qraux, RDataFactory.COMPLETE_VECTOR), + RDataFactory.createDoubleVector(y, RDataFactory.COMPLETE_VECTOR), + argValues[5], + coef, + RDataFactory.createIntVector(info, RDataFactory.COMPLETE_VECTOR), + }; + // @formatter:on + return RDataFactory.createList(data, DQRCF_NAMES); + + } catch (ClassCastException | ArrayIndexOutOfBoundsException ex) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INCORRECT_ARG, "dqrcf"); + } + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java new file mode 100644 index 0000000000000000000000000000000000000000..12dd728140716057b9bd2c6c91bcbb349b260a53 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java @@ -0,0 +1,59 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995-2012, The R Core Team + * Copyright (c) 2003, The R Foundation + * Copyright (c) 2015, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.nodes.builtin.base.foreign; + +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 final class Dqrdc2 extends RExternalBuiltinNode { + + private static final String E = RRuntime.NAMES_ATTR_EMPTY_VALUE; + private static final RStringVector DQRDC2_NAMES = RDataFactory.createStringVector(new String[]{"qr", E, E, E, E, "rank", "qraux", "pivot", E}, RDataFactory.COMPLETE_VECTOR); + + @Override + public RList call(RArgsValuesAndNames args) { + Object[] argValues = args.getArguments(); + try { + RAbstractDoubleVector xVec = (RAbstractDoubleVector) argValues[0]; + int ldx = (int) argValues[1]; + int n = (int) argValues[2]; + int p = (int) argValues[3]; + double tol = (double) argValues[4]; + RAbstractIntVector rankVec = (RAbstractIntVector) argValues[5]; + RAbstractDoubleVector qrauxVec = (RAbstractDoubleVector) argValues[6]; + RAbstractIntVector pivotVec = (RAbstractIntVector) argValues[7]; + RAbstractDoubleVector workVec = (RAbstractDoubleVector) argValues[8]; + double[] x = xVec.materialize().getDataTemp(); + int[] rank = rankVec.materialize().getDataTemp(); + double[] qraux = qrauxVec.materialize().getDataTemp(); + int[] pivot = pivotVec.materialize().getDataTemp(); + RFFIFactory.getRFFI().getRApplRFFI().dqrdc2(x, ldx, n, p, tol, rank, qraux, pivot, workVec.materialize().getDataCopy()); + // @formatter:off + Object[] data = new Object[]{ + RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR, xVec.getDimensions()), + argValues[1], argValues[2], argValues[3], argValues[4], + RDataFactory.createIntVector(rank, RDataFactory.COMPLETE_VECTOR), + RDataFactory.createDoubleVector(qraux, RDataFactory.COMPLETE_VECTOR), + RDataFactory.createIntVector(pivot, RDataFactory.COMPLETE_VECTOR), + argValues[8] + }; + // @formatter:on + return RDataFactory.createList(data, DQRDC2_NAMES); + } catch (ClassCastException | ArrayIndexOutOfBoundsException ex) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.INCORRECT_ARG, "dqrdc2"); + } + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java new file mode 100644 index 0000000000000000000000000000000000000000..9615e5e6fc32c90c4ddfe80254e5be7aa1890c5d --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java @@ -0,0 +1,89 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995-2012, The R Core Team + * Copyright (c) 2003, The R Foundation + * Copyright (c) 2015, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.nodes.builtin.base.foreign; + +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.*; +import com.oracle.truffle.r.runtime.ffi.*; + +public final class Fft extends RExternalBuiltinNode { + + private final ConditionProfile zVecLgt1 = ConditionProfile.createBinaryProfile(); + private final ConditionProfile noDims = ConditionProfile.createBinaryProfile(); + + // TODO: handle more argument types (this is sufficient to run the b25 benchmarks) + @Override + public RComplexVector call(RArgsValuesAndNames args) { + Object[] argValues = args.getArguments(); + RComplexVector zVec = castComplexVector(castVector(argValues[0])); + double[] z = zVec.getDataTemp(); + byte inverse = castLogical(castVector(argValues[1])); + int inv = RRuntime.isNA(inverse) || inverse == RRuntime.LOGICAL_FALSE ? -2 : 2; + @SuppressWarnings("unused") + int retCode = 7; + if (zVecLgt1.profile(zVec.getLength() > 1)) { + int[] maxf = new int[1]; + int[] maxp = new int[1]; + if (noDims.profile(zVec.getDimensions() == null)) { + int n = zVec.getLength(); + RFFIFactory.getRFFI().getStatsRFFI().fft_factor(n, maxf, maxp); + if (maxf[0] == 0) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.FFT_FACTORIZATION); + } + double[] work = new double[4 * maxf[0]]; + int[] iwork = new int[maxp[0]]; + retCode = RFFIFactory.getRFFI().getStatsRFFI().fft_work(z, 1, n, 1, inv, work, iwork); + } else { + int maxmaxf = 1; + int maxmaxp = 1; + int[] d = zVec.getDimensions(); + int ndims = d.length; + /* do whole loop just for error checking and maxmax[fp] .. */ + for (int i = 0; i < ndims; i++) { + if (d[i] > 1) { + RFFIFactory.getRFFI().getStatsRFFI().fft_factor(d[i], maxf, maxp); + if (maxf[0] == 0) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.FFT_FACTORIZATION); + } + if (maxf[0] > maxmaxf) { + maxmaxf = maxf[0]; + } + if (maxp[0] > maxmaxp) { + maxmaxp = maxp[0]; + } + } + } + double[] work = new double[4 * maxmaxf]; + int[] iwork = new int[maxmaxp]; + int nseg = zVec.getLength(); + int n = 1; + int nspn = 1; + for (int i = 0; i < ndims; i++) { + if (d[i] > 1) { + nspn *= n; + n = d[i]; + nseg /= n; + RFFIFactory.getRFFI().getStatsRFFI().fft_factor(n, maxf, maxp); + RFFIFactory.getRFFI().getStatsRFFI().fft_work(z, nseg, n, nspn, inv, work, iwork); + } + } + + } + } + + return RDataFactory.createComplexVector(z, zVec.isComplete(), zVec.getDimensions()); + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Flushconsole.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Flushconsole.java new file mode 100644 index 0000000000000000000000000000000000000000..3c224994053b52cdcdd979955c0ec1d7167b00e1 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Flushconsole.java @@ -0,0 +1,23 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995-2012, The R Core Team + * Copyright (c) 2003, The R Foundation + * Copyright (c) 2015, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.nodes.builtin.base.foreign; + +import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.r.runtime.data.*; + +public final class Flushconsole extends RExternalBuiltinNode { + + @Override + public RNull call(RArgsValuesAndNames args) { + return RNull.instance; + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java new file mode 100644 index 0000000000000000000000000000000000000000..897c53403c16df466c27c711e4850707311225e3 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java @@ -0,0 +1,309 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995-2012, The R Core Team + * Copyright (c) 2003, The R Foundation + * Copyright (c) 2015, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.nodes.builtin.base.foreign; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.utilities.*; +import com.oracle.truffle.r.library.graphics.GraphicsCCalls.C_Par; +import com.oracle.truffle.r.library.graphics.GraphicsCCalls.C_PlotXY; +import com.oracle.truffle.r.library.methods.MethodsListDispatchFactory.R_M_setPrimitiveMethodsNodeGen; +import com.oracle.truffle.r.library.methods.MethodsListDispatchFactory.R_getClassFromCacheNodeGen; +import com.oracle.truffle.r.library.methods.MethodsListDispatchFactory.R_initMethodDispatchNodeGen; +import com.oracle.truffle.r.library.methods.MethodsListDispatchFactory.R_methodsPackageMetaNameNodeGen; +import com.oracle.truffle.r.library.methods.MethodsListDispatchFactory.R_set_method_dispatchNodeGen; +import com.oracle.truffle.r.library.stats.*; +import com.oracle.truffle.r.library.stats.GammaFunctionsFactory.QgammaNodeGen; +import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineCoefNodeGen; +import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineEvalNodeGen; +import com.oracle.truffle.r.library.tools.*; +import com.oracle.truffle.r.library.tools.ToolsTextFactory.CodeFilesAppendNodeGen; +import com.oracle.truffle.r.library.tools.ToolsTextFactory.DoTabExpandNodeGen; +import com.oracle.truffle.r.library.utils.*; +import com.oracle.truffle.r.nodes.builtin.*; +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.model.*; +import com.oracle.truffle.r.runtime.ffi.*; +import com.oracle.truffle.r.runtime.ffi.DLL.SymbolInfo; + +/** + * {@code .Call} {@code .Fortran}, {@code .External}, {@code .External2}, {@code External.graphics} + * functions. + * + * TODO Completeness (more types, more error checks), Performance (copying). Especially all the + * subtleties around copying. + * + * See <a href="https://stat.ethz.ch/R-manual/R-devel/library/base/html/Foreign.html">here</a>. + */ +public class ForeignFunctions { + + protected abstract static class LookupAdapter extends RBuiltinNode { + + protected abstract RExternalBuiltinNode lookupBuiltin(RList f); + + private static final String UNKNOWN_EXTERNAL_BUILTIN = "UNKNOWN_EXTERNAL_BUILTIN"; + + protected String lookupName(RList f) { + if (f.getNames() != null) { + RAbstractStringVector names = f.getNames(); + for (int i = 0; i < names.getLength(); i++) { + if (names.getDataAt(i).equals("name")) { + String name = RRuntime.asString(f.getDataAt(i)); + return name != null ? name : UNKNOWN_EXTERNAL_BUILTIN; + } + } + } + return UNKNOWN_EXTERNAL_BUILTIN; + } + + protected RuntimeException fallback(Object fobj) { + String name = null; + if (fobj instanceof RList) { + name = lookupName((RList) fobj); + name = name == UNKNOWN_EXTERNAL_BUILTIN ? null : name; + if (name != null && lookupBuiltin((RList) fobj) != null) { + /* + * if we reach this point, then the cache saw a different value for f. the lists + * that contain the information about native calls are never expected to change. + */ + throw RInternalError.shouldNotReachHere("fallback reached for " + getRBuiltin().name() + " " + name); + } + } + throw RError.nyi(getEncapsulatingSourceSection(), getRBuiltin().name() + " specialization failure: " + (name == null ? "<unknown>" : name)); + } + } + + /** + * For now, just some special case functions that are built in to the implementation. + */ + @RBuiltin(name = ".Fortran", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "NAOK", "DUP", "PACKAGE", "ENCODING"}) + public abstract static class Fortran extends LookupAdapter { + + @Override + public Object[] getDefaultParameterValues() { + return new Object[]{RMissing.instance, RArgsValuesAndNames.EMPTY, RRuntime.LOGICAL_FALSE, RRuntime.LOGICAL_FALSE, RMissing.instance, RMissing.instance}; + } + + @Override + protected RExternalBuiltinNode lookupBuiltin(RList f) { + switch (lookupName(f)) { + case "dqrdc2": + return new Dqrdc2(); + case "dqrcf": + return new Dqrcf(); + default: + return null; + } + } + + @SuppressWarnings("unused") + @Specialization(limit = "1", guards = {"cached == f", "builtin != null"}) + protected Object doExternal(RList f, RArgsValuesAndNames args, byte naok, byte dup, RMissing rPackage, RMissing encoding, @Cached("f") RList cached, + @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { + controlVisibility(); + return builtin.call(args); + } + + @SuppressWarnings("unused") + @Fallback + protected Object fallback(Object f, Object args, Object naok, Object dup, Object rPackage, Object encoding) { + throw fallback(f); + } + } + + /** + * Handles the generic case, but also many special case functions that are called from the + * default packages. + */ + @RBuiltin(name = ".Call", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}) + public abstract static class DotCall extends LookupAdapter { + + private final BranchProfile errorProfile = BranchProfile.create(); + + @Override + public Object[] getDefaultParameterValues() { + return new Object[]{RMissing.instance, RArgsValuesAndNames.EMPTY, RMissing.instance}; + } + + @Override + protected RExternalBuiltinNode lookupBuiltin(RList f) { + switch (lookupName(f)) { + case "fft": + return new Fft(); + case "R_initMethodDispatch": + return R_initMethodDispatchNodeGen.create(); + case "R_methodsPackageMetaName": + return R_methodsPackageMetaNameNodeGen.create(); + case "R_set_method_dispatch": + return R_set_method_dispatchNodeGen.create(); + case "R_M_setPrimitiveMethods": + return R_M_setPrimitiveMethodsNodeGen.create(); + case "R_getClassFromCache": + return R_getClassFromCacheNodeGen.create(); + case "crc64": + return Crc64NodeGen.create(); + case "cov": + return new Covcor(false); + case "cor": + return new Covcor(true); + case "SplineCoef": + return SplineCoefNodeGen.create(); + case "SplineEval": + return SplineEvalNodeGen.create(); + case "doTabExpand": + return DoTabExpandNodeGen.create(); + case "codeFilesAppend": + return CodeFilesAppendNodeGen.create(); + case "Rmd5": + return Rmd5NodeGen.create(); + case "flushconsole": + return new Flushconsole(); + case "dirchmod": + return DirChmodNodeGen.create(); + case "cairoProps": + return CairoPropsNodeGen.create(); + case "makeQuartzDefault": + return new MakeQuartzDefault(); + default: + return null; + } + } + + @SuppressWarnings("unused") + @Specialization(limit = "1", guards = {"cached == f", "builtin != null"}) + protected Object doExternal(RList f, RArgsValuesAndNames args, RMissing packageName, @Cached("f") RList cached, @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { + controlVisibility(); + return builtin.call(args); + } + + @Specialization + public Object callNamedFunction(String name, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { + return callNamedFunctionWithPackage(name, args, null); + } + + @Specialization + public Object callNamedFunctionWithPackage(String name, RArgsValuesAndNames args, String packageName) { + controlVisibility(); + SymbolInfo symbolInfo = DLL.findSymbolInfo(name, packageName); + if (symbolInfo == null) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), Message.C_SYMBOL_NOT_IN_TABLE, name); + } + try { + return RFFIFactory.getRFFI().getCallRFFI().invokeCall(symbolInfo, args.getArguments()); + } catch (Throwable t) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NATIVE_CALL_FAILED, t.getMessage()); + } + } + + @Fallback + protected Object dotCallFallback(Object fobj, @SuppressWarnings("unused") Object args, @SuppressWarnings("unused") Object packageName) { + throw fallback(fobj); + } + } + + @RBuiltin(name = ".External", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}) + public abstract static class DotExternal extends LookupAdapter { + + @Override + protected RExternalBuiltinNode lookupBuiltin(RList f) { + switch (lookupName(f)) { + case "countfields": + return new CountFields(); + case "readtablehead": + return new ReadTableHead(); + case "rnorm": + return RnormNodeGen.create(); + case "runif": + return RunifNodeGen.create(); + case "qgamma": + return QgammaNodeGen.create(); + case "download": + return new Download(); + default: + return null; + } + } + + @SuppressWarnings("unused") + @Specialization(limit = "1", guards = {"cached == f", "builtin != null"}) + protected Object doExternal(RList f, RArgsValuesAndNames args, RMissing packageName, @Cached("f") RList cached, @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { + controlVisibility(); + return builtin.call(args); + } + + @Fallback + protected Object fallback(Object f, @SuppressWarnings("unused") Object args, @SuppressWarnings("unused") Object packageName) { + throw fallback(f); + } + } + + @RBuiltin(name = ".External2", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "..."}) + public abstract static class DotExternal2 extends LookupAdapter { + + @Override + protected RExternalBuiltinNode lookupBuiltin(RList f) { + switch (lookupName(f)) { + case "writetable": + return new WriteTable(); + case "typeconvert": + return TypeConvertNodeGen.create(); + case "C_par": + return new C_Par(); + case "C_parseRd": + return C_ParseRdNodeGen.create(); + default: + return null; + } + } + + @SuppressWarnings("unused") + @Specialization(limit = "1", guards = {"cached == f", "builtin != null"}) + protected Object doExternal(RList f, RArgsValuesAndNames args, @Cached("f") RList cached, @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { + controlVisibility(); + return builtin.call(args); + } + + @Fallback + protected Object fallback(Object f, @SuppressWarnings("unused") Object args) { + throw fallback(f); + } + } + + @RBuiltin(name = ".External.graphics", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "..."}) + public abstract static class DotExternalGraphics extends LookupAdapter { + + @Override + protected RExternalBuiltinNode lookupBuiltin(RList f) { + switch (lookupName(f)) { + case "C_plotXY": + return new C_PlotXY(); + default: + return null; + } + } + + @SuppressWarnings("unused") + @Specialization(limit = "1", guards = {"cached == f", "builtin != null"}) + protected Object doExternal(RList f, RArgsValuesAndNames args, @Cached("f") RList cached, @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { + controlVisibility(); + return builtin.call(args); + } + + @Fallback + protected Object fallback(Object f, @SuppressWarnings("unused") Object args) { + throw fallback(f); + } + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/MakeQuartzDefault.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/MakeQuartzDefault.java new file mode 100644 index 0000000000000000000000000000000000000000..2511c6c372d0a90dd76fd92d1ce9cc6b98837dc8 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/MakeQuartzDefault.java @@ -0,0 +1,24 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995-2012, The R Core Team + * Copyright (c) 2003, The R Foundation + * Copyright (c) 2015, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.nodes.builtin.base.foreign; + +import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.r.runtime.*; +import com.oracle.truffle.r.runtime.data.*; + +public final class MakeQuartzDefault extends RExternalBuiltinNode { + + @Override + public Object call(RArgsValuesAndNames args) { + return RRuntime.LOGICAL_FALSE; + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ReadTableHead.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ReadTableHead.java new file mode 100644 index 0000000000000000000000000000000000000000..4ac131f50eafca42556f2a03a45d65c98bc25e56 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ReadTableHead.java @@ -0,0 +1,36 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995-2012, The R Core Team + * Copyright (c) 2003, The R Foundation + * Copyright (c) 2015, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.nodes.builtin.base.foreign; + +import java.io.*; + +import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.r.runtime.*; +import com.oracle.truffle.r.runtime.conn.*; +import com.oracle.truffle.r.runtime.data.*; + +public final class ReadTableHead extends RExternalBuiltinNode { + + @Override + public Object call(RArgsValuesAndNames args) { + // TODO This is quite incomplete and just uses readLines, which works for some inputs + Object[] argValues = args.getArguments(); + RConnection conn = (RConnection) argValues[0]; + int nlines = castInt(castVector(argValues[1])); + try (RConnection openConn = conn.forceOpen("r")) { + return RDataFactory.createStringVector(openConn.readLines(nlines), RDataFactory.COMPLETE_VECTOR); + } catch (IOException ex) { + errorProfile.enter(); + throw RError.error(getEncapsulatingSourceSection(), RError.Message.ERROR_READING_CONNECTION, ex.getMessage()); + } + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RExternalBuiltinNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RExternalBuiltinNode.java new file mode 100644 index 0000000000000000000000000000000000000000..c290eade41d350d503158ddff21d7ce9751719d3 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RExternalBuiltinNode.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2015, 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; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.utilities.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.unary.*; +import com.oracle.truffle.r.runtime.*; +import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; + +@TypeSystemReference(RTypes.class) +public abstract class RExternalBuiltinNode extends Node { + + public abstract Object call(RArgsValuesAndNames args); + + // TODO: these should be in the build nodes + @Child private CastLogicalNode castLogical; + @Child private CastIntegerNode castInt; + @Child private CastDoubleNode castDouble; + @Child private CastComplexNode castComplex; + @Child private CastToVectorNode castVector; + + protected final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + protected final BranchProfile errorProfile = BranchProfile.create(); + + protected byte castLogical(RAbstractVector operand) { + if (castLogical == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + castLogical = insert(CastLogicalNodeGen.create(null, false, false, false)); + } + return ((RAbstractLogicalVector) castLogical.executeCast(operand)).getDataAt(0); + } + + protected int castInt(RAbstractVector operand) { + if (castInt == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + castInt = insert(CastIntegerNodeGen.create(null, false, false, false)); + } + return ((RAbstractIntVector) castInt.executeCast(operand)).getDataAt(0); + } + + protected RAbstractDoubleVector castDouble(RAbstractVector operand) { + if (castDouble == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + castDouble = insert(CastDoubleNodeGen.create(null, false, false, false)); + } + return (RAbstractDoubleVector) castDouble.executeCast(operand); + } + + protected RComplexVector castComplexVector(Object operand) { + if (castComplex == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + castComplex = insert(CastComplexNodeGen.create(null, true, true, false)); + } + return (RComplexVector) castComplex.executeCast(operand); + } + + protected RAbstractVector castVector(Object value) { + if (castVector == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + castVector = insert(CastToVectorNodeGen.create(null, false, false, false, false)); + } + return (RAbstractVector) castVector.executeObject(value); + } + + protected static String isString(Object arg) { + if (arg instanceof String) { + return (String) arg; + } else if (arg instanceof RAbstractStringVector) { + if (((RAbstractStringVector) arg).getLength() == 0) { + return null; + } else { + return ((RAbstractStringVector) arg).getDataAt(0); + } + } else { + return null; + } + } + + private static void checkLength(RArgsValuesAndNames args, int expectedLength) { + if (args.getLength() != expectedLength) { + CompilerDirectives.transferToInterpreter(); + throw RInternalError.shouldNotReachHere("mismatching number of arguments to foreign function"); + } + } + + public abstract static class Arg1 extends RExternalBuiltinNode { + public abstract Object execute(Object arg); + + @Override + public final Object call(RArgsValuesAndNames args) { + checkLength(args, 1); + return execute(args.getArgument(0)); + } + } + + public abstract static class Arg2 extends RExternalBuiltinNode { + public abstract Object execute(Object arg1, Object arg2); + + @Override + public final Object call(RArgsValuesAndNames args) { + checkLength(args, 2); + return execute(args.getArgument(0), args.getArgument(1)); + } + } + + public abstract static class Arg3 extends RExternalBuiltinNode { + public abstract Object execute(Object arg1, Object arg2, Object arg3); + + @Override + public final Object call(RArgsValuesAndNames args) { + checkLength(args, 3); + return execute(args.getArgument(0), args.getArgument(1), args.getArgument(2)); + } + } + + public abstract static class Arg4 extends RExternalBuiltinNode { + public abstract Object execute(Object arg1, Object arg2, Object arg3, Object arg4); + + @Override + public final Object call(RArgsValuesAndNames args) { + checkLength(args, 4); + return execute(args.getArgument(0), args.getArgument(1), args.getArgument(2), args.getArgument(3)); + } + } + + public abstract static class Arg5 extends RExternalBuiltinNode { + public abstract Object execute(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5); + + @Override + public final Object call(RArgsValuesAndNames args) { + checkLength(args, 5); + return execute(args.getArgument(0), args.getArgument(1), args.getArgument(2), args.getArgument(3), args.getArgument(4)); + } + } + + public abstract static class Arg6 extends RExternalBuiltinNode { + public abstract Object execute(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6); + + @Override + public final Object call(RArgsValuesAndNames args) { + checkLength(args, 6); + return execute(args.getArgument(0), args.getArgument(1), args.getArgument(2), args.getArgument(3), args.getArgument(4), args.getArgument(5)); + } + } + + public abstract static class Arg7 extends RExternalBuiltinNode { + + public abstract Object execute(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7); + + @Override + public final Object call(RArgsValuesAndNames args) { + checkLength(args, 7); + return execute(args.getArgument(0), args.getArgument(1), args.getArgument(2), args.getArgument(3), args.getArgument(4), args.getArgument(5), args.getArgument(6)); + } + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java index c56c50c4155242c348045060a7499ad59400576f..b06b98384b1e4bb5a6523278ab19b4ee6f128081 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RContext.java @@ -484,6 +484,12 @@ public final class RContext extends ExecutionContext { */ @CompilationFinal private static final ThreadLocal<RContext> threadLocalContext = new ThreadLocal<>(); + /** + * Used by the MethodListDispatch class. + */ + + private boolean methodTableDispatchOn = true; + /* * Primarily for debugging. */ @@ -754,6 +760,14 @@ public final class RContext extends ExecutionContext { resultVisible = v; } + public boolean isMethodTableDispatchOn() { + return methodTableDispatchOn; + } + + public void setMethodTableDispatchOn(boolean on) { + methodTableDispatchOn = on; + } + public boolean isInteractive() { return interactive; } diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides index 9f4a93f5050b1bd3bc57a62dc93c7c1a23890735..50ad0096e0973c63a3f7e02c80c1a05bd2847ec8 100644 --- a/mx.fastr/copyrights/overrides +++ b/mx.fastr/copyrights/overrides @@ -7,9 +7,10 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsLis com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java,gnu_r.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java,gnu_r_qgamma.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java,gnu_r.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java,gnu_r.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java,gnu_r_splines.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsUtil.java,gnu_r_ihaka.copyright -com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsDirChmod.java,gnu_r.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/DirChmod.java,gnu_r.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsText.java,gnu_r.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/CountFields.java,gnu_r.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Menu.java,gnu_r.copyright @@ -59,7 +60,15 @@ com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/D com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DuplicatedFunctions.java,purdue.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EncodeString.java,purdue.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java,gnu_r.copyright -com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ForeignFunctions.java,gnu_r.copyright +com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java,gnu_r.copyright +com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CairoProps.java,gnu_r.copyright +com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java,gnu_r.copyright +com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java,gnu_r.copyright +com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java,gnu_r.copyright +com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java,gnu_r.copyright +com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Flushconsole.java,gnu_r.copyright +com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/MakeQuartzDefault.java,gnu_r.copyright +com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ReadTableHead.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Format.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetClass.java,purdue.copyright diff --git a/mx.fastr/suite.py b/mx.fastr/suite.py index 7c221ef2260339ba01cd956ef4260b39f302c072..51f0d3b8c7bb8c4bdba0cb249e6a8872d6669687 100644 --- a/mx.fastr/suite.py +++ b/mx.fastr/suite.py @@ -362,8 +362,12 @@ suite = { "com.oracle.truffle.r.library" : { "sourceDirs" : ["src"], "dependencies" : [ + "com.oracle.truffle.r.nodes", "com.oracle.truffle.r.runtime", ], + "annotationProcessors" : [ + "com.oracle.truffle.dsl.processor", + ], "checkstyle" : "com.oracle.truffle.r.runtime", "javaCompliance" : "1.8", "workingSets" : "FastR",