From d8b2a2ef821d70daf58ea501636f0f6788949682 Mon Sep 17 00:00:00 2001
From: Zbynek Slajchrt <zbynek.slajchrt@oracle.com>
Date: Tue, 28 Mar 2017 17:52:09 +0200
Subject: [PATCH] Fixes made when integrating the checkpoint package

---
 .../truffle/r/library/utils/Download.java     | 76 +++++++++++++------
 .../r/nodes/builtin/base/Readline.java        |  3 +
 .../r/nodes/castsTests/CastBuilderTest.java   |  2 +
 .../analysis/ForwardedValuesAnalyser.java     |  2 +-
 .../r/nodes/function/ClassHierarchyNode.java  |  6 ++
 .../nodes/function/signature/MissingNode.java |  9 ++-
 .../truffle/r/test/ExpectedTestOutput.test    |  4 +
 .../r/test/builtins/TestBuiltin_missing.java  |  4 +-
 mx.fastr/copyrights/overrides                 |  1 +
 9 files changed, 81 insertions(+), 26 deletions(-)

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 b51d2be570..e3b26dca3d 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
@@ -1,24 +1,13 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 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
  *
- * 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.
+ * Copyright (c) 1995, 1996  Robert Gentleman and Ross Ihaka
+ * Copyright (c) 1997-2013,  The R Core Team
+ * Copyright (c) 2017, Oracle and/or its affiliates
  *
- * 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.
+ * All rights reserved.
  */
 package com.oracle.truffle.r.library.utils;
 
@@ -30,7 +19,9 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.HttpURLConnection;
 import java.net.URL;
+import java.net.URLConnection;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
@@ -40,6 +31,7 @@ import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.conn.StdConnections;
 
 /**
  * Support for the "internal"method of "utils::download.file". TODO take note of "quiet", "mode" and
@@ -59,12 +51,52 @@ public abstract class Download extends RExternalBuiltinNode.Arg5 {
 
     @Specialization
     @TruffleBoundary
-    protected int download(String urlString, String destFile, @SuppressWarnings("unused") boolean quiet, @SuppressWarnings("unused") String mode, @SuppressWarnings("unused") boolean cacheOK) {
+    protected int download(String urlString, String destFile, boolean quiet, @SuppressWarnings("unused") String mode, @SuppressWarnings("unused") boolean cacheOK) {
         try {
-            try (InputStream in = new URL(urlString).openStream()) {
-                Files.copy(in, Paths.get(destFile), StandardCopyOption.REPLACE_EXISTING);
+            URLConnection con = new URL(urlString).openConnection();
+            try (InputStream in = con.getInputStream()) {
+                long len = Files.copy(in, Paths.get(destFile), StandardCopyOption.REPLACE_EXISTING);
+                if (!quiet) {
+
+                    String contentType = null;
+                    if (con instanceof HttpURLConnection) {
+                        HttpURLConnection httpCon = (HttpURLConnection) con;
+                        contentType = httpCon.getContentType();
+                    }
+
+                    // Transcribed from GnuR, src/modules/internet/internet.c
+
+                    StdConnections.getStderr().writeString(String.format("Content type '%s'", contentType != null ? contentType : "unknown"), false);
+                    if (len > 1024 * 1024) {
+                        StdConnections.getStderr().writeString(String.format(" length %0.0f bytes (%0.1f MB)", (double) len, len / 1024.0 / 1024.0), true);
+                    } else if (len > 10240) {
+                        StdConnections.getStderr().writeString(String.format(" length %d bytes (%d KB)", len, len / 1024), true);
+                    } else if (len >= 0) {
+                        StdConnections.getStderr().writeString(String.format(" length %d bytes", len), true);
+                    } else {
+                        StdConnections.getStderr().writeString(" length unknown", true);
+                    }
+                    StdConnections.getStderr().flush();
+                }
+
+                return 0;
+            } catch (IOException e) {
+                if (!quiet) {
+
+                    // Transcribed from GnuR, src/modules/internet/internet.c
+
+                    int responseCode = -1;
+                    String responseMsg = null;
+                    if (con instanceof HttpURLConnection) {
+                        HttpURLConnection httpCon = (HttpURLConnection) con;
+                        responseCode = httpCon.getResponseCode();
+                        responseMsg = httpCon.getResponseMessage();
+                    }
+
+                    warning(RError.Message.GENERIC, String.format("cannot open URL '%s': HTTP status was '%d %s'", urlString, responseCode, responseMsg != null ? responseMsg : ""));
+                }
+                throw e;
             }
-            return 0;
         } catch (IOException e) {
             throw error(RError.Message.GENERIC, e.getMessage());
         }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Readline.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Readline.java
index bc5411859c..8f51dffb91 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Readline.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Readline.java
@@ -51,6 +51,9 @@ public abstract class Readline extends RBuiltinNode {
         String savedPrompt = consoleHandler.getPrompt();
         consoleHandler.setPrompt(prompt.getDataAt(0));
         String input = consoleHandler.readLine();
+        // The readLine method always appends the newline character, as opposed to the readline
+        // builtin. Therefore, the trailing newline must be cut off.
+        input = input.substring(0, input.length() - 1);
         consoleHandler.setPrompt(savedPrompt);
         return input;
     }
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastBuilderTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastBuilderTest.java
index 5e36f005de..218c1393bd 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastBuilderTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastBuilderTest.java
@@ -565,6 +565,8 @@ public class CastBuilderTest {
     public void testMustBeSquareMatrix() {
         arg.asDoubleVector(true, true, true).mustBe(squareMatrix());
 
+        assertCastFail(1.0);
+
         RIntVector vec = RDataFactory.createIntVector(new int[]{0, 1, 2, 3}, true, new int[]{2, 2});
         Object res = cast(vec);
         assertTrue(res instanceof RAbstractDoubleVector);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardedValuesAnalyser.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardedValuesAnalyser.java
index e85a6f5363..4eb716c6cc 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardedValuesAnalyser.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardedValuesAnalyser.java
@@ -260,7 +260,7 @@ public final class ForwardedValuesAnalyser implements PipelineStepVisitor<Forwar
 
             @Override
             public ForwardingAnalysisResult visit(MatrixFilter<?> filter, @SuppressWarnings("hiding") ForwardingAnalysisResult previous) {
-                return new ForwardingAnalysisResult().forwardAll();
+                return new ForwardingAnalysisResult().blockAll();
             }
 
             @Override
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
index dd4a98c595..b11b3c9f7f 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
@@ -46,6 +46,7 @@ import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RComplexVector;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
+import com.oracle.truffle.r.runtime.data.REmpty;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RLogicalVector;
@@ -110,6 +111,11 @@ public abstract class ClassHierarchyNode extends UnaryNode {
         return withImplicitTypes ? RNull.implicitClassHeader : null;
     }
 
+    @Specialization
+    protected RStringVector getClassHr(@SuppressWarnings("unused") REmpty arg) {
+        return withImplicitTypes ? RNull.implicitClassHeader : null;
+    }
+
     @Specialization
     protected RStringVector getClassHrAttributable(RAttributable arg,
                     @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/MissingNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/MissingNode.java
index abc8291e09..f7f09332ee 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/MissingNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/MissingNode.java
@@ -46,6 +46,7 @@ import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RPromise.EagerPromise;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxElement;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
 
@@ -201,10 +202,14 @@ public final class MissingNode extends OperatorNode {
                 throw error(Message.ARGUMENTS_PASSED, args.length, "'missing'", 1);
             }
             RSyntaxElement arg = args[0];
-            if (!(arg instanceof RSyntaxLookup)) {
+            String identifier;
+            if (arg instanceof RSyntaxConstant && ((RSyntaxConstant) arg).getValue() instanceof String) {
+                identifier = (String) ((RSyntaxConstant) arg).getValue();
+            } else if (arg instanceof RSyntaxLookup) {
+                identifier = ((RSyntaxLookup) arg).getIdentifier();
+            } else {
                 throw error(Message.INVALID_USE, "missing");
             }
-            String identifier = ((RSyntaxLookup) arg).getIdentifier();
             if (ArgumentsSignature.VARARG_NAME.equals(identifier)) {
                 readVarArgs = insert(LocalReadVariableNode.create(ArgumentsSignature.VARARG_NAME, false));
             } else {
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index 8e341d3b4c..8721518a96 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -36430,6 +36430,10 @@ Levels: A < B < C
 #{ f <- function(a) { g(a) } ; g <- function(b=2) { missing(b) } ; f() }
 [1] TRUE
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_missing.testMissing#
+#{ f <- function(a) { missing("a") };  f(); f(1) }
+[1] FALSE
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_missing.testMissing#
 #{ f <- function(a,b,c) { missing(b) } ; f(1,,2) }
 [1] TRUE
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_missing.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_missing.java
index 2de37d13ee..b7558998d1 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_missing.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_missing.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2012-2014, Purdue University
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -47,5 +47,7 @@ public class TestBuiltin_missing extends TestBase {
         assertEval("{ f <- function(x) { print(missing(x)); g(x) }; g <- function(y=3) { print(missing(y)); k(y) }; k <- function(l=4) { print(missing(l)); l }; f() }");
         assertEval("{ f <- function(x) { print(missing(x)) ; g(x) } ; g <- function(y=1) { print(missing(y)) ; h(y) } ; h <- function(z) { print(missing(z)) ; z } ; f() }");
         assertEval("{ f <- function(a,b,c,d,e,env) (length(objects(env, all.names = TRUE, pattern = \"^[.]__[CTA]_\"))); f2 <- function(env) (length(objects(env, all.names = TRUE, pattern = \"^[.]__[CTA]_\"))); f(); f2() }");
+
+        assertEval("{ f <- function(a) { missing(\"a\") };  f(); f(1) }");
     }
 }
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index eaa941e25e..a09bd8bac8 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -767,3 +767,4 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircle.
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/EdgeDetection.java,gnu_r_murrel_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridTextNode.java,gnu_r_murrel_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LConvert.java,gnu_r_murrel_core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Download.java,gnu_r_gentleman_ihaka2.copyright
-- 
GitLab