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 722b28dacb17e478dd15c06ff250284630549682..56e3f6ea7ab67244176fbda05380a6a9fd94a581 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 @@ -22,55 +22,51 @@ */ package com.oracle.truffle.r.library.utils; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.FileOutputStream; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.singleElement; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; + import java.io.IOException; +import java.io.InputStream; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.builtin.CastBuilder; +import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; +import com.oracle.truffle.r.runtime.RError.Message; /** * Support for the "internal"method of "utils::download.file". TODO take note of "quiet", "mode" and * "cacheOK". */ -public final class Download extends RExternalBuiltinNode { +public abstract class Download extends RExternalBuiltinNode.Arg5 { + + @Override + protected void createCasts(CastBuilder casts) { + casts.arg(0).mustNotBeNull().mustBe(stringValue()).asStringVector().mustBe(notEmpty()).shouldBe(singleElement(), Message.ONLY_FIRST_USED).findFirst(); + casts.arg(1).mustNotBeNull().mustBe(stringValue()).asStringVector().mustBe(notEmpty()).shouldBe(singleElement(), Message.ONLY_FIRST_USED).findFirst(); + casts.arg(2).mustNotBeNull().mustBe(Predef.logicalValue()).asLogicalVector().mustBe(notEmpty()).shouldBe(singleElement(), Message.ONLY_FIRST_USED).findFirst().map(toBoolean()); + casts.arg(3).mustNotBeNull().mustBe(stringValue()).asStringVector().mustBe(notEmpty()).shouldBe(singleElement(), Message.ONLY_FIRST_USED).findFirst(); + casts.arg(4).mustNotBeNull().mustBe(Predef.logicalValue()).asLogicalVector().mustBe(notEmpty()).shouldBe(singleElement(), Message.ONLY_FIRST_USED).findFirst().map(toBoolean()); - @SuppressWarnings("unused") - 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))) { - int nread; - while ((nread = in.read(buffer)) > 0) { - out.write(buffer, 0, nread); - } - } } - @Override - @TruffleBoundary - 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(this, RError.Message.INVALID_UNNAMED_ARGUMENTS); - } + @Specialization + protected int download(String urlString, String destFile, @SuppressWarnings("unused") boolean quiet, @SuppressWarnings("unused") String mode, @SuppressWarnings("unused") boolean cacheOK) { try { - Download.download(url, destFile, RRuntime.fromLogical(quiet), mode, RRuntime.fromLogical(cacheOK)); + try (InputStream in = new URL(urlString).openStream()) { + Files.copy(in, Paths.get(destFile), StandardCopyOption.REPLACE_EXISTING); + } return 0; - } catch (IOException ex) { + } catch (IOException e) { errorProfile.enter(); - throw RError.error(this, RError.Message.GENERIC, ex.getMessage()); + throw RError.error(this, RError.Message.GENERIC, e.getMessage()); } } } 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 index c21a68dff92002ed458483a2e6f1bd213a71b212..c15e41e81848edfec4ae9ad06f1ebbac9a6a7850 100644 --- 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 @@ -11,28 +11,32 @@ */ package com.oracle.truffle.r.nodes.builtin.base.foreign; +import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.builtin.CastBuilder; +import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; -public final class Fft extends RExternalBuiltinNode { +public abstract class Fft extends RExternalBuiltinNode.Arg2 { 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; + protected void createCasts(CastBuilder casts) { + casts.arg(0).mustNotBeNull().asComplexVector(false, true, false); + casts.arg(1).mustNotBeNull().asLogicalVector().findFirst().map(Predef.toBoolean()); + } + + // TODO: handle more argument types (this is sufficient to run the b25 benchmarks) + @Specialization + public Object execute(RAbstractComplexVector zVec, boolean inverse) { + double[] z = zVec.materialize().getDataTemp(); + int inv = inverse ? 2 : -2; @SuppressWarnings("unused") int retCode = 7; if (zVecLgt1.profile(zVec.getLength() > 1)) { @@ -83,10 +87,8 @@ public final class Fft extends RExternalBuiltinNode { 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/ForeignFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java index 17e80124f170c7340513e15007e815296906f3d0..24c3e23bd4335004ef30be42e6ecbf572e6e52da 100644 --- 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 @@ -64,7 +64,7 @@ import com.oracle.truffle.r.library.tools.ToolsTextFactory.CodeFilesAppendNodeGe import com.oracle.truffle.r.library.tools.ToolsTextFactory.DoTabExpandNodeGen; import com.oracle.truffle.r.library.utils.CountFields; import com.oracle.truffle.r.library.utils.Crc64NodeGen; -import com.oracle.truffle.r.library.utils.Download; +import com.oracle.truffle.r.library.utils.DownloadNodeGen; import com.oracle.truffle.r.library.utils.MenuNodeGen; import com.oracle.truffle.r.library.utils.ObjectSizeNodeGen; import com.oracle.truffle.r.library.utils.RprofNodeGen; @@ -343,7 +343,7 @@ public class ForeignFunctions { // stats case "fft": - return new Fft(); + return FftNodeGen.create(); case "cov": return new Covcor(false); case "cor": @@ -583,7 +583,7 @@ public class ForeignFunctions { case "readtablehead": return new ReadTableHead(); case "download": - return new Download(); + return DownloadNodeGen.create(); case "termsform": return getExternalModelBuiltinNode("termsform"); case "Rprof": 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 index 35a7a115fdba2156732aa2c70f394fbc151f9378..2b27980e31203978e15b7d3d61e985b3d0ebbca3 100644 --- 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 @@ -27,7 +27,6 @@ import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.unary.CastComplexNode; -import com.oracle.truffle.r.nodes.unary.CastComplexNodeGen; import com.oracle.truffle.r.nodes.unary.CastDoubleNode; import com.oracle.truffle.r.nodes.unary.CastDoubleNodeGen; import com.oracle.truffle.r.nodes.unary.CastIntegerNode; @@ -40,7 +39,6 @@ import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RTypes; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -107,14 +105,6 @@ public abstract class RExternalBuiltinNode extends RBaseNode { return (RAbstractDoubleVector) castDouble.execute(operand); } - protected RComplexVector castComplexVector(Object operand) { - if (castComplex == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castComplex = insert(CastComplexNodeGen.create(true, true, false)); - } - return (RComplexVector) castComplex.execute(operand); - } - protected RAbstractVector castVector(Object value) { if (castVector == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java index bec9e0943e38390c5ec2f598f6edd3255ecc0949..7f6d3923f831bd495ec9be66d0acbc55933de585 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java @@ -27,6 +27,7 @@ import com.oracle.truffle.r.nodes.builtin.casts.Filter; import com.oracle.truffle.r.nodes.builtin.casts.Mapper; import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep; import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RRaw; @@ -147,8 +148,8 @@ public class InitialPhaseBuilder<T> extends ArgCastBuilder<T, InitialPhaseBuilde return this; } - public CoercedPhaseBuilder<RAbstractIntVector, Integer> asIntegerVector(boolean preserveNames, boolean dimensionsPreservation, boolean attrPreservation) { - pipelineBuilder().appendAsIntegerVector(preserveNames, dimensionsPreservation, attrPreservation); + public CoercedPhaseBuilder<RAbstractIntVector, Integer> asIntegerVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + pipelineBuilder().appendAsVector(RType.Integer, preserveNames, preserveDimensions, preserveAttributes); return new CoercedPhaseBuilder<>(pipelineBuilder(), Integer.class); } @@ -156,8 +157,8 @@ public class InitialPhaseBuilder<T> extends ArgCastBuilder<T, InitialPhaseBuilde return asIntegerVector(false, false, false); } - public CoercedPhaseBuilder<RAbstractDoubleVector, Double> asDoubleVector(boolean preserveNames, boolean dimensionsPreservation, boolean attrPreservation) { - pipelineBuilder().appendAsDoubleVector(preserveNames, dimensionsPreservation, attrPreservation); + public CoercedPhaseBuilder<RAbstractDoubleVector, Double> asDoubleVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + pipelineBuilder().appendAsVector(RType.Double, preserveNames, preserveDimensions, preserveAttributes); return new CoercedPhaseBuilder<>(pipelineBuilder(), Double.class); } @@ -165,8 +166,8 @@ public class InitialPhaseBuilder<T> extends ArgCastBuilder<T, InitialPhaseBuilde return asDoubleVector(false, false, false); } - public CoercedPhaseBuilder<RAbstractDoubleVector, Byte> asLogicalVector(boolean preserveNames, boolean dimensionsPreservation, boolean attrPreservation) { - pipelineBuilder().appendAsLogicalVector(preserveNames, dimensionsPreservation, attrPreservation); + public CoercedPhaseBuilder<RAbstractDoubleVector, Byte> asLogicalVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + pipelineBuilder().appendAsVector(RType.Logical, preserveNames, preserveDimensions, preserveAttributes); return new CoercedPhaseBuilder<>(pipelineBuilder(), Byte.class); } @@ -174,28 +175,35 @@ public class InitialPhaseBuilder<T> extends ArgCastBuilder<T, InitialPhaseBuilde return asLogicalVector(false, false, false); } - public CoercedPhaseBuilder<RAbstractStringVector, String> asStringVector(boolean preserveNames, boolean dimensionsPreservation, boolean attrPreservation) { - pipelineBuilder().appendAsStringVector(preserveNames, dimensionsPreservation, attrPreservation); + public CoercedPhaseBuilder<RAbstractStringVector, String> asStringVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + pipelineBuilder().appendAsVector(RType.Character, preserveNames, preserveDimensions, preserveAttributes); return new CoercedPhaseBuilder<>(pipelineBuilder(), String.class); } public CoercedPhaseBuilder<RAbstractStringVector, String> asStringVector() { - pipelineBuilder().appendAsStringVector(); - return new CoercedPhaseBuilder<>(pipelineBuilder(), String.class); + return asStringVector(false, false, false); } - public CoercedPhaseBuilder<RAbstractComplexVector, RComplex> asComplexVector() { - pipelineBuilder().appendAsComplexVector(); + public CoercedPhaseBuilder<RAbstractComplexVector, RComplex> asComplexVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + pipelineBuilder().appendAsVector(RType.Complex, preserveNames, preserveDimensions, preserveAttributes); return new CoercedPhaseBuilder<>(pipelineBuilder(), RComplex.class); } - public CoercedPhaseBuilder<RAbstractRawVector, RRaw> asRawVector() { - pipelineBuilder().appendAsRawVector(); + public CoercedPhaseBuilder<RAbstractComplexVector, RComplex> asComplexVector() { + return asComplexVector(false, false, false); + } + + public CoercedPhaseBuilder<RAbstractRawVector, RRaw> asRawVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + pipelineBuilder().appendAsVector(RType.Raw, preserveNames, preserveDimensions, preserveAttributes); return new CoercedPhaseBuilder<>(pipelineBuilder(), RRaw.class); } + public CoercedPhaseBuilder<RAbstractRawVector, RRaw> asRawVector() { + return asRawVector(false, false, false); + } + public CoercedPhaseBuilder<RAbstractVector, Object> asVector() { - pipelineBuilder().appendAsVector(); + pipelineBuilder().appendAsVector(false, false, false, true); return new CoercedPhaseBuilder<>(pipelineBuilder(), Object.class); } @@ -209,8 +217,8 @@ public class InitialPhaseBuilder<T> extends ArgCastBuilder<T, InitialPhaseBuilde return new CoercedPhaseBuilder<>(pipelineBuilder(), Object.class); } - public HeadPhaseBuilder<RAttributable> asAttributable(boolean preserveNames, boolean dimensionsPreservation, boolean attrPreservation) { - pipelineBuilder().appendAsAttributable(preserveNames, dimensionsPreservation, attrPreservation); + public HeadPhaseBuilder<RAttributable> asAttributable(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + pipelineBuilder().appendAsAttributable(preserveNames, preserveDimensions, preserveAttributes); return new HeadPhaseBuilder<>(pipelineBuilder()); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java index d94cda9d6252bd54f651fa854de6e91ea3be13ad..f2dee59fd83941231c746f099fde11090ce8d07e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java @@ -78,44 +78,17 @@ public final class PipelineBuilder { append(new FindFirstStep<>(defaultValue, elementClass, createMessage(callObj, message, messageArgs))); } - public void appendAsAttributable(boolean preserveNames, boolean dimensionsPreservation, boolean attrPreservation) { - append(new AttributableCoercionStep<>(preserveNames, dimensionsPreservation, attrPreservation)); + public void appendAsAttributable(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + append(new AttributableCoercionStep<>(preserveNames, preserveDimensions, preserveAttributes)); } public void appendAsVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean preserveNonVector) { append(new CoercionStep<>(RType.Any, true, preserveNames, preserveDimensions, preserveAttributes, preserveNonVector)); } - public void appendAsVector() { - appendAsVector(false, false, false, true); - } - - public void appendAsRawVector() { - append(new CoercionStep<>(RType.Raw, true, false, false, false)); - } - - public void appendAsComplexVector() { - append(new CoercionStep<>(RType.Complex, true, false, false, false)); - } - - public void appendAsStringVector(boolean preserveNames, boolean dimensionsPreservation, boolean attrPreservation) { - append(new CoercionStep<>(RType.Character, true, preserveNames, dimensionsPreservation, attrPreservation)); - } - - public void appendAsStringVector() { - append(new CoercionStep<>(RType.Character, true, false, false, false)); - } - - public void appendAsLogicalVector(boolean preserveNames, boolean dimensionsPreservation, boolean attrPreservation) { - append(new CoercionStep<>(RType.Logical, true, preserveNames, dimensionsPreservation, attrPreservation)); - } - - public void appendAsDoubleVector(boolean preserveNames, boolean dimensionsPreservation, boolean attrPreservation) { - append(new CoercionStep<>(RType.Double, true, preserveNames, dimensionsPreservation, attrPreservation)); - } - - public void appendAsIntegerVector(boolean preserveNames, boolean dimensionsPreservation, boolean attrPreservation) { - append(new CoercionStep<>(RType.Integer, true, preserveNames, dimensionsPreservation, attrPreservation)); + public void appendAsVector(RType type, boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + assert type == RType.Integer || type == RType.Double || type == RType.Complex || type == RType.Character || type == RType.Logical || type == RType.Raw; + append(new CoercionStep<>(type, true, preserveNames, preserveDimensions, preserveAttributes)); } public void appendNotNA(Object naReplacement, RBaseNode callObj, Message message, Object[] messageArgs) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java index e065ee7ee029f40cad33eb76f369a8b8f9530630..dfb8e2e97b1d12f58330500058dfd69e5e064b27 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java @@ -745,7 +745,8 @@ public final class RError extends RuntimeException { APPLIES_TO_VECTORS("%s applies only to vectors"), GAP_MUST_BE_NON_NEGATIVE("'gap' must be non-negative integer"), WRONG_PCRE_INFO("'pcre_fullinfo' returned '%d' "), - BAD_FUNCTION_EXPR("badly formed function expression"); + BAD_FUNCTION_EXPR("badly formed function expression"), + FIRST_ELEMENT_ONLY("only first element of '%s' argument used"); public final String message; final boolean hasArgs;