Revert "Method Handles: Add VarargsCollector."

This reverts commit ab52ce1480d9c4701bfe3ff3530596ec0c5760ee.

Change-Id: Idc6dd28b58a61cbd2c9ee72e8a0eeb07b2ca0edf
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index d098ee2..05f74d6 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -922,7 +922,7 @@
         ThrowWrongMethodTypeException(check_type.Ptr(), callsite_type.Get());
         return false;
       }
-    } else if (!IsInvokeTransform(handle_kind)) {
+    } else {
       if (UNLIKELY(!IsCallerTransformer(callsite_type) &&
                    !callsite_type->IsConvertible(check_type.Ptr()))) {
         ThrowWrongMethodTypeException(check_type.Ptr(), callsite_type.Get());
@@ -990,37 +990,33 @@
       CHECK(called_method != nullptr);
     }
 
-    if (IsInvokeTransform(handle_kind)) {
-      // There are two cases here - method handles representing regular
-      // transforms and those representing call site transforms. Method
-      // handles for call site transforms adapt their MethodType to match
-      // the call site. For these, the |callee_type| is the same as the
-      // |callsite_type|. The VarargsCollector is such a tranform, its
-      // method type depends on the call site, ie. x(a) or x(a, b), or
-      // x(a, b, c). The VarargsCollector invokes a variable arity method
-      // with the arity arguments in an array.
-      Handle<mirror::MethodType> callee_type =
-          (handle_kind == kInvokeCallSiteTransform) ? callsite_type : handle_type;
-      return DoCallTransform<is_range>(called_method,
-                                       callsite_type,
-                                       callee_type,
-                                       self,
-                                       shadow_frame,
-                                       method_handle /* receiver */,
-                                       result,
-                                       arg,
-                                       first_src_reg);
+    bool call_success;
+    if (handle_kind == kInvokeTransform) {
+      call_success = DoCallTransform<is_range>(called_method,
+                                               callsite_type,
+                                               handle_type,
+                                               self,
+                                               shadow_frame,
+                                               method_handle /* receiver */,
+                                               result,
+                                               arg,
+                                               first_src_reg);
     } else {
-      return DoCallPolymorphic<is_range>(called_method,
-                                         callsite_type,
-                                         handle_type,
-                                         self,
-                                         shadow_frame,
-                                         result,
-                                         arg,
-                                         first_src_reg,
-                                         handle_kind);
+      call_success = DoCallPolymorphic<is_range>(called_method,
+                                                 callsite_type,
+                                                 handle_type,
+                                                 self,
+                                                 shadow_frame,
+                                                 result,
+                                                 arg,
+                                                 first_src_reg,
+                                                 handle_kind);
     }
+    if (LIKELY(call_success && ConvertReturnValue(callsite_type, handle_type, result))) {
+      return true;
+    }
+    DCHECK(self->IsExceptionPending());
+    return false;
   } else {
     DCHECK(!is_range);
     ArtField* field = method_handle->GetTargetField();
@@ -1101,6 +1097,7 @@
   return num_ins;
 }
 
+
 inline void PerformCall(Thread* self,
                         const DexFile::CodeItem* code_item,
                         ArtMethod* caller_method,
@@ -1254,31 +1251,18 @@
   }
 
   PerformCall(self, code_item, shadow_frame.GetMethod(), first_dest_reg, new_shadow_frame, result);
-  if (self->IsExceptionPending()) {
-    return false;
-  }
 
   // If the caller of this signature polymorphic method was a transformer,
   // we need to copy the result back out to the emulated stack frame.
-  if (is_caller_transformer) {
-    StackHandleScope<2> hs(self);
-    Handle<mirror::EmulatedStackFrame> emulated_stack_frame(
-        hs.NewHandle(reinterpret_cast<mirror::EmulatedStackFrame*>(
-            shadow_frame.GetVRegReference(first_src_reg))));
-    Handle<mirror::MethodType> emulated_stack_type(hs.NewHandle(emulated_stack_frame->GetType()));
-    JValue local_result;
-    local_result.SetJ(result->GetJ());
+  if (is_caller_transformer && !self->IsExceptionPending()) {
+    ObjPtr<mirror::EmulatedStackFrame> emulated_stack_frame(
+        reinterpret_cast<mirror::EmulatedStackFrame*>(
+            shadow_frame.GetVRegReference(first_src_reg)));
 
-    if (ConvertReturnValue(emulated_stack_type, target_type, &local_result)) {
-      emulated_stack_frame->SetReturnValue(self, local_result);
-      return true;
-    } else {
-      DCHECK(self->IsExceptionPending());
-      return false;
-    }
-  } else {
-    return ConvertReturnValue(callsite_type, target_type, result);
+    emulated_stack_frame->SetReturnValue(self, *result);
   }
+
+  return !self->IsExceptionPending();
 }
 
 template <bool is_range>
@@ -1345,14 +1329,14 @@
               0 /* first dest reg */,
               new_shadow_frame,
               result);
-  if (self->IsExceptionPending()) {
-    return false;
-  }
 
   // If the called transformer method we called has returned a value, then we
   // need to copy it back to |result|.
-  sf->GetReturnValue(self, result);
-  return ConvertReturnValue(callsite_type, callee_type, result);
+  if (!self->IsExceptionPending()) {
+    sf->GetReturnValue(self, result);
+  }
+
+  return !self->IsExceptionPending();
 }
 
 template <bool is_range,
diff --git a/runtime/method_handles.h b/runtime/method_handles.h
index d0a4902..54c772a 100644
--- a/runtime/method_handles.h
+++ b/runtime/method_handles.h
@@ -46,13 +46,12 @@
   kInvokeStatic,
   kInvokeInterface,
   kInvokeTransform,
-  kInvokeCallSiteTransform,
   kInstanceGet,
   kInstancePut,
   kStaticGet,
   kStaticPut,
   kLastValidKind = kStaticPut,
-  kLastInvokeKind = kInvokeCallSiteTransform
+  kLastInvokeKind = kInvokeTransform
 };
 
 // Whether the given method handle kind is some variant of an invoke.
@@ -60,11 +59,6 @@
   return handle_kind <= kLastInvokeKind;
 }
 
-// Whether the given method handle kind is some variant of a tranform.
-inline bool IsInvokeTransform(const MethodHandleKind handle_kind) {
-  return handle_kind == kInvokeTransform || handle_kind == kInvokeCallSiteTransform;
-}
-
 // Returns true if there is a possible conversion from |from| to |to|
 // for a MethodHandle parameter.
 bool IsParameterTypeConvertible(ObjPtr<mirror::Class> from,
diff --git a/runtime/mirror/emulated_stack_frame.h b/runtime/mirror/emulated_stack_frame.h
index d83a536..9fa06b7 100644
--- a/runtime/mirror/emulated_stack_frame.h
+++ b/runtime/mirror/emulated_stack_frame.h
@@ -58,10 +58,6 @@
   // Sets the return value slot of this emulated stack frame to |value|.
   void SetReturnValue(Thread* self, const JValue& value) REQUIRES_SHARED(Locks::mutator_lock_);
 
-  mirror::MethodType* GetType() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return GetFieldObject<MethodType>(OFFSET_OF_OBJECT_MEMBER(EmulatedStackFrame, type_));
-  }
-
   static void SetClass(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
   static void ResetClass() REQUIRES_SHARED(Locks::mutator_lock_);
   static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
@@ -71,6 +67,10 @@
     return static_class_.Read();
   }
 
+  mirror::MethodType* GetType() REQUIRES_SHARED(Locks::mutator_lock_) {
+    return GetFieldObject<MethodType>(OFFSET_OF_OBJECT_MEMBER(EmulatedStackFrame, type_));
+  }
+
   mirror::ObjectArray<mirror::Object>* GetReferences() REQUIRES_SHARED(Locks::mutator_lock_) {
     return GetFieldObject<mirror::ObjectArray<mirror::Object>>(
         OFFSET_OF_OBJECT_MEMBER(EmulatedStackFrame, references_));
diff --git a/test/956-methodhandles/expected.txt b/test/956-methodhandles/expected.txt
index 9b09327..0a5caa1 100644
--- a/test/956-methodhandles/expected.txt
+++ b/test/956-methodhandles/expected.txt
@@ -7,11 +7,3 @@
 String constructors done.
 testReferenceReturnValueConversions done.
 testPrimitiveReturnValueConversions done.
-Hi
-Hi
-Hi
-Hi
-Expect Hi here: Hi
-Don't expect Hi now
-[3, 2, 1]
-[1, 2, 3]
diff --git a/test/956-methodhandles/src/Main.java b/test/956-methodhandles/src/Main.java
index ee9c436..8713caa 100644
--- a/test/956-methodhandles/src/Main.java
+++ b/test/956-methodhandles/src/Main.java
@@ -19,14 +19,13 @@
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.invoke.MethodType;
 import java.lang.invoke.WrongMethodTypeException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
 
 public class Main {
 
@@ -75,7 +74,6 @@
     testConstructors();
     testStringConstructors();
     testReturnValueConversions();
-    testVariableArity();
   }
 
   public static void testfindSpecial_invokeSuperBehaviour() throws Throwable {
@@ -557,34 +555,6 @@
     }
   }
 
-  public static void assertTrue(boolean value) {
-    if (!value) {
-      throw new AssertionError("assertTrue value: " + value);
-    }
-  }
-
-  public static void assertFalse(boolean value) {
-    if (value) {
-      throw new AssertionError("assertTrue value: " + value);
-    }
-  }
-
-  public static void assertEquals(int i1, int i2) {
-    if (i1 == i2) { return; }
-    throw new AssertionError("assertEquals i1: " + i1 + ", i2: " + i2);
-  }
-
-  public static void assertEquals(long i1, long i2) {
-    if (i1 == i2) { return; }
-    throw new AssertionError("assertEquals l1: " + i1 + ", l2: " + i2);
-  }
-
-  public static void assertEquals(Object o, Object p) {
-    if (o == p) { return; }
-    if (o != null && p != null && o.equals(p)) { return; }
-    throw new AssertionError("assertEquals: o1: " + o + ", o2: " + p);
-  }
-
   public static void assertEquals(String s1, String s2) {
     if (s1 == s2) {
       return;
@@ -990,480 +960,4 @@
     testReferenceReturnValueConversions();
     testPrimitiveReturnValueConversions();
   }
-
-  public static class BaseVariableArityTester {
-    public String update(Float f0, Float... floats) {
-      return "base " + f0 + ", " + Arrays.toString(floats);
-    }
-  }
-
-  public static class VariableArityTester extends BaseVariableArityTester {
-    private String lastResult;
-
-    // Constructors
-    public VariableArityTester() {}
-    public VariableArityTester(boolean... booleans) { update(booleans); }
-    public VariableArityTester(byte... bytes) { update(bytes); }
-    public VariableArityTester(char... chars) { update(chars); }
-    public VariableArityTester(short... shorts) { update(shorts); }
-    public VariableArityTester(int... ints) { update(ints); }
-    public VariableArityTester(long... longs) { update(longs); }
-    public VariableArityTester(float... floats) { update(floats); }
-    public VariableArityTester(double... doubles) { update(doubles); }
-    public VariableArityTester(Float f0, Float... floats) { update(f0, floats); }
-    public VariableArityTester(String s0, String... strings) { update(s0, strings); }
-    public VariableArityTester(char c, Number... numbers) { update(c, numbers); }
-    @SafeVarargs
-    public VariableArityTester(ArrayList<Integer> l0, ArrayList<Integer>... lists) {
-      update(l0, lists);
-    }
-    public VariableArityTester(List l0, List... lists) { update(l0, lists); }
-
-    // Methods
-    public String update(boolean... booleans) { return lastResult = tally(booleans); }
-    public String update(byte... bytes) { return lastResult = tally(bytes); }
-    public String update(char... chars) { return lastResult = tally(chars); }
-    public String update(short... shorts) { return lastResult = tally(shorts); }
-    public String update(int... ints) {
-      lastResult = tally(ints);
-      return lastResult;
-    }
-    public String update(long... longs) { return lastResult = tally(longs); }
-    public String update(float... floats) { return lastResult = tally(floats); }
-    public String update(double... doubles) { return lastResult = tally(doubles); }
-    @Override
-    public String update(Float f0, Float... floats) { return lastResult = tally(f0, floats); }
-    public String update(String s0, String... strings) { return lastResult = tally(s0, strings); }
-    public String update(char c, Number... numbers) { return lastResult = tally(c, numbers); }
-    @SafeVarargs
-    public final String update(ArrayList<Integer> l0, ArrayList<Integer>... lists) {
-      lastResult = tally(l0, lists);
-      return lastResult;
-    }
-    public String update(List l0, List... lists) { return lastResult = tally(l0, lists); }
-
-    public String arrayMethod(Object[] o) {
-      return Arrays.deepToString(o);
-    }
-
-    public String lastResult() { return lastResult; }
-
-    // Static Methods
-    public static String tally(boolean... booleans) { return Arrays.toString(booleans); }
-    public static String tally(byte... bytes) { return Arrays.toString(bytes); }
-    public static String tally(char... chars) { return Arrays.toString(chars); }
-    public static String tally(short... shorts) { return Arrays.toString(shorts); }
-    public static String tally(int... ints) { return Arrays.toString(ints); }
-    public static String tally(long... longs) { return Arrays.toString(longs); }
-    public static String tally(float... floats) { return Arrays.toString(floats); }
-    public static String tally(double... doubles) { return Arrays.toString(doubles); }
-    public static String tally(Float f0, Float... floats) {
-      return f0 + ", " + Arrays.toString(floats);
-    }
-    public static String tally(String s0, String... strings) {
-      return s0 + ", " + Arrays.toString(strings);
-    }
-    public static String tally(char c, Number... numbers) {
-      return c + ", " + Arrays.toString(numbers);
-    }
-    @SafeVarargs
-    public static String tally(ArrayList<Integer> l0, ArrayList<Integer>... lists) {
-      return Arrays.toString(l0.toArray()) + ", " + Arrays.deepToString(lists);
-    }
-    public static String tally(List l0, List... lists) {
-      return Arrays.deepToString(l0.toArray()) + ", " + Arrays.deepToString(lists);
-    }
-    public static void foo(int... ints) { System.out.println(Arrays.toString(ints)); }
-    public static long sumToPrimitive(int... ints) {
-      long result = 0;
-      for (int i : ints) result += i;
-      return result;
-    }
-    public static Long sumToReference(int... ints) {
-      System.err.println("Hi");
-      return new Long(sumToPrimitive(ints));
-    }
-    public static MethodHandles.Lookup lookup() {
-      return MethodHandles.lookup();
-    }
-  }
-
-  // This method only exists to fool Jack's handling of types. See b/32536744.
-  public static Object getAsObject(String[] strings) {
-    return (Object) strings;
-  }
-
-  public static void testVariableArity() throws Throwable {
-    MethodHandle mh;
-    VariableArityTester vat = new VariableArityTester();
-
-    assertEquals("[1]", vat.update(1));
-    assertEquals("[1, 1]", vat.update(1, 1));
-    assertEquals("[1, 1, 1]", vat.update(1, 1, 1));
-
-    // Methods - boolean
-    mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update",
-                                            MethodType.methodType(String.class, boolean[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertFalse(mh.asFixedArity().isVarargsCollector());
-    assertEquals("[]", mh.invoke(vat));
-    assertEquals("[true, false, true]", mh.invoke(vat, true, false, true));
-    assertEquals("[true, false, true]", mh.invoke(vat, new boolean[] { true, false, true}));
-    assertEquals("[false, true]", mh.invoke(vat, Boolean.valueOf(false), Boolean.valueOf(true)));
-    try {
-      mh.invoke(vat, true, true, 0);
-      fail();
-    } catch (WrongMethodTypeException e) {}
-    try {
-      assertEquals("[false, true]", mh.invoke(vat, Boolean.valueOf(false), (Boolean) null));
-      fail();
-    } catch (NullPointerException e) {}
-
-    // Methods - byte
-    mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update",
-                                            MethodType.methodType(String.class, byte[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("[]", mh.invoke(vat));
-    assertEquals("[32, 64, 97]", mh.invoke(vat, (byte) 32, Byte.valueOf((byte) 64), (byte) 97));
-    assertEquals("[32, 64, 97]", mh.invoke(vat, new byte[] {(byte) 32, (byte) 64, (byte) 97}));
-    try {
-      mh.invoke(vat, (byte) 1, Integer.valueOf(3), (byte) 0);
-      fail();
-    } catch (WrongMethodTypeException e) {}
-
-    // Methods - char
-    mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update",
-                                            MethodType.methodType(String.class, char[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("[]", mh.invoke(vat));
-    assertEquals("[A, B, C]", mh.invoke(vat, 'A', Character.valueOf('B'), 'C'));
-    assertEquals("[W, X, Y, Z]", mh.invoke(vat, new char[] { 'W', 'X', 'Y', 'Z' }));
-
-    // Methods - short
-    mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update",
-                                            MethodType.methodType(String.class, short[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("[]", mh.invoke(vat));
-    assertEquals("[32767, -32768, 0]",
-                 mh.invoke(vat, Short.MAX_VALUE, Short.MIN_VALUE, Short.valueOf((short) 0)));
-    assertEquals("[1, -1]", mh.invoke(vat, new short[] { (short) 1, (short) -1 }));
-
-    // Methods - int
-    mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update",
-                                            MethodType.methodType(String.class, int[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("[]", mh.invoke(vat));
-    assertEquals("[0, 2147483647, -2147483648, 0]",
-                 mh.invoke(vat, Integer.valueOf(0), Integer.MAX_VALUE, Integer.MIN_VALUE, 0));
-    assertEquals("[0, -1, 1, 0]", mh.invoke(vat, new int[] { 0, -1, 1, 0 }));
-
-    assertEquals("[5, 4, 3, 2, 1]", (String) mh.invokeExact(vat, new int [] { 5, 4, 3, 2, 1 }));
-    try {
-      assertEquals("[5, 4, 3, 2, 1]", (String) mh.invokeExact(vat, 5, 4, 3, 2, 1));
-      fail();
-    } catch (WrongMethodTypeException e) {}
-    assertEquals("[5, 4, 3, 2, 1]", (String) mh.invoke(vat, 5, 4, 3, 2, 1));
-
-    // Methods - long
-    mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update",
-                                            MethodType.methodType(String.class, long[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("[]", mh.invoke(vat));
-    assertEquals("[0, 9223372036854775807, -9223372036854775808]",
-                 mh.invoke(vat, Long.valueOf(0), Long.MAX_VALUE, Long.MIN_VALUE));
-    assertEquals("[0, -1, 1, 0]", mh.invoke(vat, new long[] { 0, -1, 1, 0 }));
-
-    // Methods - float
-    mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update",
-                                            MethodType.methodType(String.class, float[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("[]", mh.invoke(vat));
-    assertEquals("[0.0, 1.25, -1.25]",
-                 mh.invoke(vat, 0.0f, Float.valueOf(1.25f), Float.valueOf(-1.25f)));
-    assertEquals("[0.0, -1.0, 1.0, 0.0]",
-                 mh.invoke(vat, new float[] { 0.0f, -1.0f, 1.0f, 0.0f }));
-
-    // Methods - double
-    mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update",
-                                            MethodType.methodType(String.class, double[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("[]", mh.invoke(vat));
-    assertEquals("[0.0, 1.25, -1.25]",
-                 mh.invoke(vat, 0.0, Double.valueOf(1.25), Double.valueOf(-1.25)));
-    assertEquals("[0.0, -1.0, 1.0, 0.0]",
-                 mh.invoke(vat, new double[] { 0.0, -1.0, 1.0, 0.0 }));
-    mh.invoke(vat, 0.3f, 1.33, 1.33);
-
-    // Methods - String
-    mh = MethodHandles.lookup().
-        findVirtual(VariableArityTester.class, "update",
-                    MethodType.methodType(String.class, String.class, String[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("Echidna, []", mh.invoke(vat, "Echidna"));
-    assertEquals("Bongo, [Jerboa, Okapi]",
-                 mh.invoke(vat, "Bongo", "Jerboa", "Okapi"));
-
-    // Methods - Float
-    mh = MethodHandles.lookup().
-        findVirtual(VariableArityTester.class, "update",
-                    MethodType.methodType(String.class, Float.class, Float[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("9.99, [0.0, 0.1, 1.1]",
-                 (String) mh.invoke(vat, Float.valueOf(9.99f),
-                                    new Float[] { Float.valueOf(0.0f),
-                                                  Float.valueOf(0.1f),
-                                                  Float.valueOf(1.1f) }));
-    assertEquals("9.99, [0.0, 0.1, 1.1]",
-                 (String) mh.invoke(vat, Float.valueOf(9.99f), Float.valueOf(0.0f),
-                                    Float.valueOf(0.1f), Float.valueOf(1.1f)));
-    assertEquals("9.99, [0.0, 0.1, 1.1]",
-                 (String) mh.invoke(vat, Float.valueOf(9.99f), 0.0f, 0.1f, 1.1f));
-    try {
-      assertEquals("9.99, [77.0, 33.0, 64.0]",
-                   (String) mh.invoke(vat, Float.valueOf(9.99f), 77, 33, 64));
-      fail();
-    } catch (WrongMethodTypeException e) {}
-    assertEquals("9.99, [0.0, 0.1, 1.1]",
-                 (String) mh.invokeExact(vat, Float.valueOf(9.99f),
-                                         new Float[] { Float.valueOf(0.0f),
-                                                       Float.valueOf(0.1f),
-                                                       Float.valueOf(1.1f) }));
-    assertEquals("9.99, [0.0, null, 1.1]",
-                 (String) mh.invokeExact(vat, Float.valueOf(9.99f),
-                                         new Float[] { Float.valueOf(0.0f),
-                                                       null,
-                                                       Float.valueOf(1.1f) }));
-    try {
-      assertEquals("9.99, [0.0, 0.1, 1.1]",
-                   (String) mh.invokeExact(vat, Float.valueOf(9.99f), 0.0f, 0.1f, 1.1f));
-      fail();
-    } catch (WrongMethodTypeException e) {}
-
-    // Methods - Number
-    mh = MethodHandles.lookup().
-        findVirtual(VariableArityTester.class, "update",
-                    MethodType.methodType(String.class, char.class, Number[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertFalse(mh.asFixedArity().isVarargsCollector());
-    assertEquals("x, []",  (String) mh.invoke(vat, 'x'));
-    assertEquals("x, [3.141]", (String) mh.invoke(vat, 'x', 3.141));
-    assertEquals("x, [null, 3.131, 37]",
-                 (String) mh.invoke(vat, 'x', null, 3.131, new Integer(37)));
-    try {
-      assertEquals("x, [null, 3.131, bad, 37]",
-                   (String) mh.invoke(vat, 'x', null, 3.131, "bad", new Integer(37)));
-      assertTrue(false);
-      fail();
-    } catch (ClassCastException e) {}
-    try {
-      assertEquals("x, [null, 3.131, bad, 37]",
-                   (String) mh.invoke(
-                       vat, 'x', (Process) null, 3.131, "bad", new Integer(37)));
-      assertTrue(false);
-      fail();
-    } catch (ClassCastException e) {}
-
-    // Methods - an array method that is not variable arity.
-    mh = MethodHandles.lookup().findVirtual(
-        VariableArityTester.class, "arrayMethod",
-        MethodType.methodType(String.class, Object[].class));
-    assertFalse(mh.isVarargsCollector());
-    mh.invoke(vat, new Object[] { "123" });
-    try {
-      assertEquals("-", mh.invoke(vat, new Float(3), new Float(4)));
-      fail();
-    } catch (WrongMethodTypeException e) {}
-    mh = mh.asVarargsCollector(Object[].class);
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("[3.0, 4.0]", (String) mh.invoke(vat, new Float(3), new Float(4)));
-
-    // Constructors - default
-    mh = MethodHandles.lookup().findConstructor(
-        VariableArityTester.class, MethodType.methodType(void.class));
-    assertFalse(mh.isVarargsCollector());
-
-    // Constructors - boolean
-    mh = MethodHandles.lookup().findConstructor(
-        VariableArityTester.class, MethodType.methodType(void.class, boolean[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("[true, true, false]",
-                 ((VariableArityTester) mh.invoke(new boolean[] {true, true, false})).lastResult());
-    assertEquals("[true, true, false]",
-                 ((VariableArityTester) mh.invoke(true, true, false)).lastResult());
-    try {
-      assertEquals("[true, true, false]",
-                   ((VariableArityTester) mh.invokeExact(true, true, false)).lastResult());
-      fail();
-    } catch (WrongMethodTypeException e) {}
-
-    // Constructors - byte
-    mh = MethodHandles.lookup().findConstructor(
-        VariableArityTester.class, MethodType.methodType(void.class, byte[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("[55, 66, 60]",
-                 ((VariableArityTester)
-                  mh.invoke(new byte[] {(byte) 55, (byte) 66, (byte) 60})).lastResult());
-    assertEquals("[55, 66, 60]",
-                 ((VariableArityTester) mh.invoke(
-                     (byte) 55, (byte) 66, (byte) 60)).lastResult());
-    try {
-      assertEquals("[55, 66, 60]",
-                   ((VariableArityTester) mh.invokeExact(
-                       (byte) 55, (byte) 66, (byte) 60)).lastResult());
-      fail();
-    } catch (WrongMethodTypeException e) {}
-    try {
-      assertEquals("[3, 3]",
-                   ((VariableArityTester) mh.invoke(
-                       new Number[] { Byte.valueOf((byte) 3), (byte) 3})).lastResult());
-      fail();
-    } catch (WrongMethodTypeException e) {}
-
-    // Constructors - String (have a different path than other reference types).
-    mh = MethodHandles.lookup().findConstructor(
-        VariableArityTester.class, MethodType.methodType(void.class, String.class, String[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("x, []", ((VariableArityTester) mh.invoke("x")).lastResult());
-    assertEquals("x, [y]", ((VariableArityTester) mh.invoke("x", "y")).lastResult());
-    assertEquals("x, [y, z]",
-                 ((VariableArityTester) mh.invoke("x", new String[] { "y", "z" })).lastResult());
-    try {
-      assertEquals("x, [y]", ((VariableArityTester) mh.invokeExact("x", "y")).lastResult());
-      fail();
-    } catch (WrongMethodTypeException e) {}
-    assertEquals("x, [null, z]",
-                 ((VariableArityTester) mh.invoke("x", new String[] { null, "z" })).lastResult());
-
-    // Constructors - Number
-    mh = MethodHandles.lookup().findConstructor(
-        VariableArityTester.class, MethodType.methodType(void.class, char.class, Number[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertFalse(mh.asFixedArity().isVarargsCollector());
-    assertEquals("x, []", ((VariableArityTester) mh.invoke('x')).lastResult());
-    assertEquals("x, [3.141]", ((VariableArityTester) mh.invoke('x', 3.141)).lastResult());
-    assertEquals("x, [null, 3.131, 37]",
-                 ((VariableArityTester) mh.invoke('x', null, 3.131, new Integer(37))).lastResult());
-    try {
-      assertEquals("x, [null, 3.131, bad, 37]",
-                   ((VariableArityTester) mh.invoke(
-                       'x', null, 3.131, "bad", new Integer(37))).lastResult());
-      assertTrue(false);
-      fail();
-    } catch (ClassCastException e) {}
-    try {
-      assertEquals("x, [null, 3.131, bad, 37]",
-                   ((VariableArityTester) mh.invoke(
-                       'x', (Process) null, 3.131, "bad", new Integer(37))).lastResult());
-      assertTrue(false);
-      fail();
-    } catch (ClassCastException e) {}
-
-    // Static Methods - Float
-    mh = MethodHandles.lookup().
-        findStatic(VariableArityTester.class, "tally",
-                   MethodType.methodType(String.class, Float.class, Float[].class));
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("9.99, [0.0, 0.1, 1.1]",
-                 (String) mh.invoke(Float.valueOf(9.99f),
-                                    new Float[] { Float.valueOf(0.0f),
-                                                  Float.valueOf(0.1f),
-                                                  Float.valueOf(1.1f) }));
-    assertEquals("9.99, [0.0, 0.1, 1.1]",
-                 (String) mh.invoke(Float.valueOf(9.99f), Float.valueOf(0.0f),
-                                    Float.valueOf(0.1f), Float.valueOf(1.1f)));
-    assertEquals("9.99, [0.0, 0.1, 1.1]",
-                 (String) mh.invoke(Float.valueOf(9.99f), 0.0f, 0.1f, 1.1f));
-    try {
-      assertEquals("9.99, [77.0, 33.0, 64.0]",
-                   (String) mh.invoke(Float.valueOf(9.99f), 77, 33, 64));
-      fail();
-    } catch (WrongMethodTypeException e) {}
-    assertEquals("9.99, [0.0, 0.1, 1.1]",
-                 (String) mh.invokeExact(Float.valueOf(9.99f),
-                                         new Float[] { Float.valueOf(0.0f),
-                                                       Float.valueOf(0.1f),
-                                                       Float.valueOf(1.1f) }));
-    assertEquals("9.99, [0.0, null, 1.1]",
-                 (String) mh.invokeExact(Float.valueOf(9.99f),
-                                         new Float[] { Float.valueOf(0.0f),
-                                                       null,
-                                                       Float.valueOf(1.1f) }));
-    try {
-      assertEquals("9.99, [0.0, 0.1, 1.1]",
-                   (String) mh.invokeExact(Float.valueOf(9.99f), 0.0f, 0.1f, 1.1f));
-      fail();
-    } catch (WrongMethodTypeException e) {}
-
-    // Special methods - Float
-    mh = VariableArityTester.lookup().
-            findSpecial(BaseVariableArityTester.class, "update",
-                        MethodType.methodType(String.class, Float.class, Float[].class),
-                        VariableArityTester.class);
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("base 9.99, [0.0, 0.1, 1.1]",
-    (String) mh.invoke(vat,
-                       Float.valueOf(9.99f),
-                       new Float[] { Float.valueOf(0.0f),
-                                     Float.valueOf(0.1f),
-                                     Float.valueOf(1.1f) }));
-    assertEquals("base 9.99, [0.0, 0.1, 1.1]",
-    (String) mh.invoke(vat, Float.valueOf(9.99f), Float.valueOf(0.0f),
-                       Float.valueOf(0.1f), Float.valueOf(1.1f)));
-
-    // Return value conversions.
-    mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update",
-                                            MethodType.methodType(String.class, int[].class));
-    assertEquals("[1, 2, 3]", (String) mh.invoke(vat, 1, 2, 3));
-    assertEquals("[1, 2, 3]", (Object) mh.invoke(vat, 1, 2, 3));
-    try {
-      assertEquals("[1, 2, 3, 4]", (long) mh.invoke(vat, 1, 2, 3));
-      fail();
-    } catch (WrongMethodTypeException e) {}
-    assertEquals("[1, 2, 3]", vat.lastResult());
-    mh = MethodHandles.lookup().findStatic(VariableArityTester.class, "sumToPrimitive",
-                                           MethodType.methodType(long.class, int[].class));
-    assertEquals(10l, (long) mh.invoke(1, 2, 3, 4));
-    assertEquals(Long.valueOf(10l), (Long) mh.invoke(1, 2, 3, 4));
-    mh = MethodHandles.lookup().findStatic(VariableArityTester.class, "sumToReference",
-                                           MethodType.methodType(Long.class, int[].class));
-    Object o = mh.invoke(1, 2, 3, 4);
-    long l = (long) mh.invoke(1, 2, 3, 4);
-    assertEquals(10l, (long) mh.invoke(1, 2, 3, 4));
-    assertEquals(Long.valueOf(10l), (Long) mh.invoke(1, 2, 3, 4));
-    try {
-      // WrongMethodTypeException should be raised before invoke here.
-      System.err.print("Expect Hi here: ");
-      assertEquals(Long.valueOf(10l), (Byte) mh.invoke(1, 2, 3, 4));
-      fail();
-    } catch (ClassCastException e) {}
-    try {
-      // WrongMethodTypeException should be raised before invoke here.
-      System.err.println("Don't expect Hi now");
-      byte b = (byte) mh.invoke(1, 2, 3, 4);
-      fail();
-    } catch (WrongMethodTypeException e) {}
-
-    // Return void produces 0 / null.
-    mh = MethodHandles.lookup().findStatic(VariableArityTester.class, "foo",
-                                           MethodType.methodType(void.class, int[].class));
-    assertEquals(null, (Object) mh.invoke(3, 2, 1));
-    assertEquals(0l, (long) mh.invoke(1, 2, 3));
-
-    // Combinators
-    mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update",
-                                            MethodType.methodType(String.class, boolean[].class));
-    assertTrue(mh.isVarargsCollector());
-    mh = mh.bindTo(vat);
-    assertFalse(mh.isVarargsCollector());
-    mh = mh.asVarargsCollector(boolean[].class);
-    assertTrue(mh.isVarargsCollector());
-    assertEquals("[]", mh.invoke());
-    assertEquals("[true, false, true]", mh.invoke(true, false, true));
-    assertEquals("[true, false, true]", mh.invoke(new boolean[] { true, false, true}));
-    assertEquals("[false, true]", mh.invoke(Boolean.valueOf(false), Boolean.valueOf(true)));
-    try {
-      mh.invoke(true, true, 0);
-      fail();
-    } catch (WrongMethodTypeException e) {}
-  }
 }