From cab08b52331873a12cfd046772a136fbb59ba65f Mon Sep 17 00:00:00 2001
From: Adam Welc <adam.welc@oracle.com>
Date: Sun, 28 Aug 2016 14:07:29 -0700
Subject: [PATCH] Rewritten parameter casts for the tabulate builtin.

---
 .../r/nodes/builtin/base/Tabulate.java        | 20 +++----------------
 .../r/test/builtins/TestBuiltin_tabulate.java |  6 ++++++
 2 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java
index ef4df37440..17cff1e738 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java
@@ -10,13 +10,11 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
-import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.LoopConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -30,22 +28,16 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 @RBuiltin(name = "tabulate", kind = INTERNAL, parameterNames = {"bin", "nbins"}, behavior = PURE)
 public abstract class Tabulate extends RBuiltinNode {
 
-    private final BranchProfile errorProfile = BranchProfile.create();
     private final LoopConditionProfile loopProfile = LoopConditionProfile.createCountingProfile();
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        // TODO: not sure if the behavior is 100% compliant
-        casts.arg("bin").asIntegerVector();
-        casts.arg("nbins").asIntegerVector().findFirst();
+        casts.arg("bin").mustBe(integerValue(), RError.NO_CALLER, RError.Message.INVALID_INPUT).asIntegerVector();
+        casts.arg("nbins").defaultError(RError.NO_CALLER, RError.Message.INVALID_ARGUMENT, "nbin").asIntegerVector().findFirst().mustBe(gte(0));
     }
 
     @Specialization
     protected RIntVector tabulate(RAbstractIntVector bin, int nBins) {
-        if (RRuntime.isNA(nBins) || nBins < 0) {
-            errorProfile.enter();
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "nbin");
-        }
         int[] ans = new int[nBins];
         loopProfile.profileCounted(bin.getLength());
         for (int i = 0; loopProfile.inject(i < bin.getLength()); i++) {
@@ -57,10 +49,4 @@ public abstract class Tabulate extends RBuiltinNode {
         return RDataFactory.createIntVector(ans, RDataFactory.COMPLETE_VECTOR);
     }
 
-    @SuppressWarnings("unused")
-    @Fallback
-    @TruffleBoundary
-    protected RIntVector tabulate(Object bin, Object nBins) {
-        throw RError.error(this, RError.Message.INVALID_INPUT);
-    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tabulate.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tabulate.java
index 8e671d9096..edfddef077 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tabulate.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tabulate.java
@@ -59,5 +59,11 @@ public class TestBuiltin_tabulate extends TestBase {
         assertEval("{tabulate(c(-2,0,2,3,3,5))}");
         assertEval("{tabulate(c(-2,0,2,3,3,5), nbins = 3)}");
         assertEval("{tabulate(factor(letters[1:10]))}");
+
+        assertEval("{ .Internal(tabulate(c(2,3,5), 7)) }");
+        assertEval("{ .Internal(tabulate(c(2L,3L,5L), c(7, 42))) }");
+        assertEval("{ .Internal(tabulate(c(2L,3L,5L), integer())) }");
+        assertEval("{ .Internal(tabulate(c(2L,3L,5L), -1)) }");
+        assertEval("{ .Internal(tabulate(c(2L,3L,5L), NA)) }");
     }
 }
-- 
GitLab