jdk/src/share/classes/java/lang/invoke/SpreadGeneric.java
changeset 10204 bbd2c5e0ce05
parent 10203 cca843a7d258
parent 10174 e63dffa79ddb
child 10205 de9223c94f9c
equal deleted inserted replaced
10203:cca843a7d258 10204:bbd2c5e0ce05
     1 /*
       
     2  * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package java.lang.invoke;
       
    27 
       
    28 import sun.invoke.util.ValueConversions;
       
    29 import java.lang.reflect.Constructor;
       
    30 import java.lang.reflect.InvocationTargetException;
       
    31 import java.util.ArrayList;
       
    32 import static java.lang.invoke.MethodHandleStatics.*;
       
    33 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
       
    34 
       
    35 /**
       
    36  * Generic spread adapter.
       
    37  * Expands a final argument into multiple (zero or more) arguments, keeping the others the same.
       
    38  * @author jrose
       
    39  */
       
    40 class SpreadGeneric {
       
    41     // type for the outgoing call
       
    42     private final MethodType targetType;
       
    43     // number of arguments to spread
       
    44     private final int spreadCount;
       
    45     // prototype adapter (clone and customize for each new target!)
       
    46     private final Adapter adapter;
       
    47     // entry point for adapter (Adapter mh, a...) => ...
       
    48     private final MethodHandle entryPoint;
       
    49 
       
    50     /** Compute and cache information common to all spreading adapters
       
    51      *  that accept calls of the given (generic) type.
       
    52      */
       
    53     private SpreadGeneric(MethodType targetType, int spreadCount) {
       
    54         assert(targetType == targetType.generic());
       
    55         this.targetType = targetType;
       
    56         this.spreadCount = spreadCount;
       
    57         // the target invoker will generally need casts on reference arguments
       
    58         MethodHandle[] ep = { null };
       
    59         Adapter ad = findAdapter(this, ep);
       
    60         if (ad != null) {
       
    61             this.adapter = ad;
       
    62             this.entryPoint = ep[0];
       
    63             return;
       
    64         }
       
    65         this.adapter = buildAdapterFromBytecodes(targetType, spreadCount, ep);
       
    66         this.entryPoint = ep[0];
       
    67     }
       
    68 
       
    69     static {
       
    70         assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
       
    71     }
       
    72 
       
    73     /** From targetType remove the last spreadCount arguments, and instead
       
    74      *  append a simple Object argument.
       
    75      */
       
    76     static MethodType preSpreadType(MethodType targetType, int spreadCount) {
       
    77         @SuppressWarnings("unchecked")
       
    78         ArrayList<Class<?>> params = new ArrayList(targetType.parameterList());
       
    79         int outargs = params.size();
       
    80         params.subList(outargs - spreadCount, outargs).clear();
       
    81         params.add(Object.class);
       
    82         return MethodType.methodType(targetType.returnType(), params);
       
    83     }
       
    84 
       
    85     MethodHandle makeInstance(MethodHandle target) {
       
    86         MethodType type = target.type();
       
    87         if (type != targetType) {
       
    88             throw new UnsupportedOperationException("NYI type="+type);
       
    89         }
       
    90         return adapter.makeInstance(this, target);
       
    91     }
       
    92 
       
    93     /** Build an adapter of the given generic type, which invokes typedTarget
       
    94      *  on the incoming arguments, after unboxing as necessary.
       
    95      *  The return value is boxed if necessary.
       
    96      * @param genericType  the required type of the result
       
    97      * @param typedTarget the target
       
    98      * @return an adapter method handle
       
    99      */
       
   100     public static MethodHandle make(MethodHandle target, int spreadCount) {
       
   101         MethodType type = target.type();
       
   102         MethodType gtype = type.generic();
       
   103         if (type == gtype) {
       
   104             return SpreadGeneric.of(type, spreadCount).makeInstance(target);
       
   105         } else {
       
   106             MethodHandle gtarget = FromGeneric.make(target);
       
   107             assert(gtarget.type() == gtype);
       
   108             MethodHandle gspread = SpreadGeneric.of(gtype, spreadCount).makeInstance(gtarget);
       
   109             return ToGeneric.make(preSpreadType(type, spreadCount), gspread);
       
   110         }
       
   111     }
       
   112 
       
   113     /** Return the adapter information for this type's erasure. */
       
   114     static SpreadGeneric of(MethodType targetType, int spreadCount) {
       
   115         if (targetType != targetType.generic())
       
   116             throw new UnsupportedOperationException("NYI type="+targetType);
       
   117         MethodTypeForm form = targetType.form();
       
   118         int outcount = form.parameterCount();
       
   119         assert(spreadCount <= outcount);
       
   120         SpreadGeneric[] spreadGens = form.spreadGeneric;
       
   121         if (spreadGens == null)
       
   122             form.spreadGeneric = spreadGens = new SpreadGeneric[outcount+1];
       
   123         SpreadGeneric spreadGen = spreadGens[spreadCount];
       
   124         if (spreadGen == null)
       
   125             spreadGens[spreadCount] = spreadGen = new SpreadGeneric(form.erasedType(), spreadCount);
       
   126         return spreadGen;
       
   127     }
       
   128 
       
   129     String debugString() {
       
   130         return getClass().getSimpleName()+targetType+"["+spreadCount+"]";
       
   131     }
       
   132 
       
   133     // This mini-api is called from an Adapter to manage the spread.
       
   134     /** A check/coercion that happens once before any selections. */
       
   135     protected Object check(Object av, int n) {
       
   136         checkSpreadArgument(av, n);
       
   137         return av;
       
   138     }
       
   139 
       
   140     /** The selection operator for spreading; note that it takes Object not Object[]. */
       
   141     protected Object select(Object av, int n) {
       
   142         return ((Object[])av)[n];
       
   143     }
       
   144     /*
       
   145     protected int select_I(Object av, int n) {
       
   146         // maybe return ((int[])select)[n]
       
   147         throw new UnsupportedOperationException("subclass resp.");
       
   148     }
       
   149     protected int select_J(Object av, int n) {
       
   150         // maybe return ((long[])select)[n]
       
   151         throw new UnsupportedOperationException("subclass resp.");
       
   152     }
       
   153     // */
       
   154 
       
   155     /* Create an adapter that handles spreading calls for the given type. */
       
   156     static Adapter findAdapter(SpreadGeneric outer, MethodHandle[] ep) {
       
   157         MethodType targetType = outer.targetType;
       
   158         int spreadCount = outer.spreadCount;
       
   159         int outargs = targetType.parameterCount();
       
   160         int inargs = outargs - spreadCount;
       
   161         if (inargs < 0)  return null;
       
   162         MethodType entryType = MethodType.genericMethodType(inargs + 1); // 1 for av
       
   163         String cname1 = "S" + outargs;
       
   164         String[] cnames = { cname1 };
       
   165         String iname = "invoke_S"+spreadCount;
       
   166         // e.g., D5I2, D5, L5I2, L5; invoke_D5
       
   167         for (String cname : cnames) {
       
   168             Class<? extends Adapter> acls = Adapter.findSubClass(cname);
       
   169             if (acls == null)  continue;
       
   170             // see if it has the required invoke method
       
   171             MethodHandle entryPoint = null;
       
   172             try {
       
   173                 entryPoint = IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
       
   174             } catch (ReflectiveOperationException ex) {
       
   175             }
       
   176             if (entryPoint == null)  continue;
       
   177             Constructor<? extends Adapter> ctor = null;
       
   178             try {
       
   179                 ctor = acls.getDeclaredConstructor(SpreadGeneric.class);
       
   180             } catch (NoSuchMethodException ex) {
       
   181             } catch (SecurityException ex) {
       
   182             }
       
   183             if (ctor == null)  continue;
       
   184             try {
       
   185                 // Produce an instance configured as a prototype.
       
   186                 Adapter ad = ctor.newInstance(outer);
       
   187                 ep[0] = entryPoint;
       
   188                 return ad;
       
   189             } catch (IllegalArgumentException ex) {
       
   190             } catch (InvocationTargetException wex) {
       
   191                 Throwable ex = wex.getTargetException();
       
   192                 if (ex instanceof Error)  throw (Error)ex;
       
   193                 if (ex instanceof RuntimeException)  throw (RuntimeException)ex;
       
   194             } catch (InstantiationException ex) {
       
   195             } catch (IllegalAccessException ex) {
       
   196             }
       
   197         }
       
   198         return null;
       
   199     }
       
   200 
       
   201     static Adapter buildAdapterFromBytecodes(MethodType targetType,
       
   202             int spreadCount, MethodHandle[] ep) {
       
   203         throw new UnsupportedOperationException("NYI");
       
   204     }
       
   205 
       
   206     /**
       
   207      * This adapter takes some untyped arguments, and returns an untyped result.
       
   208      * Internally, it applies the invoker to the target, which causes the
       
   209      * objects to be unboxed; the result is a raw type in L/I/J/F/D.
       
   210      * This result is passed to convert, which is responsible for
       
   211      * converting the raw result into a boxed object.
       
   212      * The invoker is kept separate from the target because it can be
       
   213      * generated once per type erasure family, and reused across adapters.
       
   214      */
       
   215     static abstract class Adapter extends BoundMethodHandle {
       
   216         /*
       
   217          * class X<<R,int M,int N>> extends Adapter {
       
   218          *   (Object**N)=>R target;
       
   219          *   static int S = N-M;
       
   220          *   Object invoke(Object**M a, Object v) = target(a..., v[0]...v[S-1]);
       
   221          * }
       
   222          */
       
   223         protected final SpreadGeneric outer;
       
   224         protected final MethodHandle target;   // (any**N) => R
       
   225 
       
   226         @Override
       
   227         String debugString() {
       
   228             return addTypeString(target, this);
       
   229         }
       
   230 
       
   231         static final MethodHandle NO_ENTRY = ValueConversions.identity();
       
   232 
       
   233         protected boolean isPrototype() { return target == null; }
       
   234         protected Adapter(SpreadGeneric outer) {
       
   235             super(NO_ENTRY);
       
   236             this.outer = outer;
       
   237             this.target = null;
       
   238             assert(isPrototype());
       
   239         }
       
   240 
       
   241         protected Adapter(SpreadGeneric outer, MethodHandle target) {
       
   242             super(outer.entryPoint);
       
   243             this.outer = outer;
       
   244             this.target = target;
       
   245         }
       
   246 
       
   247         /** Make a copy of self, with new fields. */
       
   248         protected abstract Adapter makeInstance(SpreadGeneric outer, MethodHandle target);
       
   249         // { return new ThisType(outer, target); }
       
   250 
       
   251         protected Object check(Object av, int n) {
       
   252             return outer.check(av, n);
       
   253         }
       
   254         protected Object select(Object av, int n) {
       
   255             return outer.select(av, n);
       
   256         }
       
   257 
       
   258         static private final String CLASS_PREFIX; // "java.lang.invoke.SpreadGeneric$"
       
   259         static {
       
   260             String aname = Adapter.class.getName();
       
   261             String sname = Adapter.class.getSimpleName();
       
   262             if (!aname.endsWith(sname))  throw new InternalError();
       
   263             CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
       
   264         }
       
   265         /** Find a sibing class of Adapter. */
       
   266         static Class<? extends Adapter> findSubClass(String name) {
       
   267             String cname = Adapter.CLASS_PREFIX + name;
       
   268             try {
       
   269                 return Class.forName(cname).asSubclass(Adapter.class);
       
   270             } catch (ClassNotFoundException ex) {
       
   271                 return null;
       
   272             } catch (ClassCastException ex) {
       
   273                 return null;
       
   274             }
       
   275         }
       
   276     }
       
   277 
       
   278     /* generated classes follow this pattern:
       
   279     static class xS2 extends Adapter {
       
   280         protected xS2(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   281         protected xS2(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   282         protected xS2 makeInstance(SpreadGeneric outer, MethodHandle t) { return new xS2(outer, t); }
       
   283         protected Object invoke_S0(Object a0, Object a1, Object av) throws Throwable { av = super.check(av,0);
       
   284              return target.invokeExact(a0, a1)); }
       
   285         protected Object invoke_S1(Object a0, Object av) throws Throwable { av = super.check(av,1);
       
   286              return target.invokeExact(a0,
       
   287                 super.select(av,0)); }
       
   288         protected Object invoke_S2(Object a0, Object av) throws Throwable { av = super.check(av,1);
       
   289              return target.invokeExact(
       
   290                 super.select(av,0), super.select(av,1)); }
       
   291     }
       
   292     // */
       
   293 
       
   294 /*
       
   295 : SHELL; n=SpreadGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -cp . genclasses) >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
       
   296 //{{{
       
   297 import java.util.*;
       
   298 class genclasses {
       
   299     static String[][] TEMPLATES = { {
       
   300         "@for@ N=0..10",
       
   301         "    //@each-cat@",
       
   302         "    static class @cat@ extends Adapter {",
       
   303         "        protected @cat@(SpreadGeneric outer) { super(outer); }  // to build prototype",
       
   304         "        protected @cat@(SpreadGeneric outer, MethodHandle t) { super(outer, t); }",
       
   305         "        protected @cat@ makeInstance(SpreadGeneric outer, MethodHandle t) { return new @cat@(outer, t); }",
       
   306         "        protected Object invoke_S0(@Tvav,@Object av) throws Throwable { av = super.check(av, 0);",
       
   307         "            return target.invokeExact(@av@); }",
       
   308         "        //@each-S@",
       
   309         "        protected Object invoke_S@S@(@Tvav,@Object av) throws Throwable { av = super.check(av, @S@);",
       
   310         "            return target.invokeExact(@av,@@sv@); }",
       
   311         "        //@end-S@",
       
   312         "    }",
       
   313     } };
       
   314     static final String NEWLINE_INDENT = "\n                ";
       
   315     enum VAR {
       
   316         cat, N, S, av, av_, Tvav_, sv;
       
   317         public final String pattern = "@"+toString().replace('_','.')+"@";
       
   318         public String binding = toString();
       
   319         static void makeBindings(boolean topLevel, int outargs, int spread) {
       
   320             int inargs = outargs - spread;
       
   321             VAR.cat.binding = "S"+outargs;
       
   322             VAR.N.binding = String.valueOf(outargs); // outgoing arg count
       
   323             VAR.S.binding = String.valueOf(spread);  // spread count
       
   324             String[] av = new String[inargs];
       
   325             String[] Tvav = new String[inargs];
       
   326             for (int i = 0; i < inargs; i++) {
       
   327                 av[i] = arg(i);
       
   328                 Tvav[i] = param("Object", av[i]);
       
   329             }
       
   330             VAR.av.binding = comma(av);
       
   331             VAR.av_.binding = comma(av, ", ");
       
   332             VAR.Tvav_.binding = comma(Tvav, ", ");
       
   333             String[] sv = new String[spread];
       
   334             for (int i = 0; i < spread; i++) {
       
   335                 String spc = "";
       
   336                 if (i % 4 == 0) spc = NEWLINE_INDENT;
       
   337                 sv[i] = spc+"super.select(av,"+i+")";
       
   338             }
       
   339             VAR.sv.binding = comma(sv);
       
   340         }
       
   341         static String arg(int i) { return "a"+i; }
       
   342         static String param(String t, String a) { return t+" "+a; }
       
   343         static String comma(String[] v) { return comma(v, ""); }
       
   344         static String comma(String[] v, String sep) {
       
   345             if (v.length == 0)  return "";
       
   346             String res = v[0];
       
   347             for (int i = 1; i < v.length; i++)  res += ", "+v[i];
       
   348             return res + sep;
       
   349         }
       
   350         static String transform(String string) {
       
   351             for (VAR var : values())
       
   352                 string = string.replaceAll(var.pattern, var.binding);
       
   353             return string;
       
   354         }
       
   355     }
       
   356     static String[] stringsIn(String[] strings, int beg, int end) {
       
   357         return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
       
   358     }
       
   359     static String[] stringsBefore(String[] strings, int pos) {
       
   360         return stringsIn(strings, 0, pos);
       
   361     }
       
   362     static String[] stringsAfter(String[] strings, int pos) {
       
   363         return stringsIn(strings, pos, strings.length);
       
   364     }
       
   365     static int indexAfter(String[] strings, int pos, String tag) {
       
   366         return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
       
   367     }
       
   368     static int indexBefore(String[] strings, int pos, String tag) {
       
   369         for (int i = pos, end = strings.length; ; i++) {
       
   370             if (i == end || strings[i].endsWith(tag))  return i;
       
   371         }
       
   372     }
       
   373     static int MIN_ARITY, MAX_ARITY;
       
   374     public static void main(String... av) {
       
   375         for (String[] template : TEMPLATES) {
       
   376             int forLinesLimit = indexBefore(template, 0, "@each-cat@");
       
   377             String[] forLines = stringsBefore(template, forLinesLimit);
       
   378             template = stringsAfter(template, forLinesLimit);
       
   379             for (String forLine : forLines)
       
   380                 expandTemplate(forLine, template);
       
   381         }
       
   382     }
       
   383     static void expandTemplate(String forLine, String[] template) {
       
   384         String[] params = forLine.split("[^0-9]+");
       
   385         if (params[0].length() == 0)  params = stringsAfter(params, 1);
       
   386         System.out.println("//params="+Arrays.asList(params));
       
   387         int pcur = 0;
       
   388         MIN_ARITY = Integer.valueOf(params[pcur++]);
       
   389         MAX_ARITY = Integer.valueOf(params[pcur++]);
       
   390         if (pcur != params.length)  throw new RuntimeException("bad extra param: "+forLine);
       
   391         for (int outargs = MIN_ARITY; outargs <= MAX_ARITY; outargs++) {
       
   392             expandTemplate(template, true, outargs, 0);
       
   393         }
       
   394     }
       
   395     static void expandTemplate(String[] template, boolean topLevel, int outargs, int spread) {
       
   396         VAR.makeBindings(topLevel, outargs, spread);
       
   397         for (int i = 0; i < template.length; i++) {
       
   398             String line = template[i];
       
   399             if (line.endsWith("@each-cat@")) {
       
   400                 // ignore
       
   401             } else if (line.endsWith("@each-S@")) {
       
   402                 int blockEnd = indexAfter(template, i, "@end-S@");
       
   403                 String[] block = stringsIn(template, i+1, blockEnd-1);
       
   404                 for (int spread1 = spread+1; spread1 <= outargs; spread1++)
       
   405                     expandTemplate(block, false, outargs, spread1);
       
   406                 VAR.makeBindings(topLevel, outargs, spread);
       
   407                 i = blockEnd-1; continue;
       
   408             } else {
       
   409                 System.out.println(VAR.transform(line));
       
   410             }
       
   411         }
       
   412     }
       
   413 }
       
   414 //}}} */
       
   415 //params=[0, 10]
       
   416     static class S0 extends Adapter {
       
   417         protected S0(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   418         protected S0(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   419         protected S0 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S0(outer, t); }
       
   420         protected Object invoke_S0(Object av) throws Throwable { av = super.check(av, 0);
       
   421             return target.invokeExact(); }
       
   422     }
       
   423     static class S1 extends Adapter {
       
   424         protected S1(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   425         protected S1(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   426         protected S1 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S1(outer, t); }
       
   427         protected Object invoke_S0(Object a0, Object av) throws Throwable { av = super.check(av, 0);
       
   428             return target.invokeExact(a0); }
       
   429         protected Object invoke_S1(Object av) throws Throwable { av = super.check(av, 1);
       
   430             return target.invokeExact(
       
   431                 super.select(av,0)); }
       
   432     }
       
   433     static class S2 extends Adapter {
       
   434         protected S2(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   435         protected S2(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   436         protected S2 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S2(outer, t); }
       
   437         protected Object invoke_S0(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 0);
       
   438             return target.invokeExact(a0, a1); }
       
   439         protected Object invoke_S1(Object a0, Object av) throws Throwable { av = super.check(av, 1);
       
   440             return target.invokeExact(a0,
       
   441                 super.select(av,0)); }
       
   442         protected Object invoke_S2(Object av) throws Throwable { av = super.check(av, 2);
       
   443             return target.invokeExact(
       
   444                 super.select(av,0), super.select(av,1)); }
       
   445     }
       
   446     static class S3 extends Adapter {
       
   447         protected S3(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   448         protected S3(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   449         protected S3 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S3(outer, t); }
       
   450         protected Object invoke_S0(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 0);
       
   451             return target.invokeExact(a0, a1, a2); }
       
   452         protected Object invoke_S1(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 1);
       
   453             return target.invokeExact(a0, a1,
       
   454                 super.select(av,0)); }
       
   455         protected Object invoke_S2(Object a0, Object av) throws Throwable { av = super.check(av, 2);
       
   456             return target.invokeExact(a0,
       
   457                 super.select(av,0), super.select(av,1)); }
       
   458         protected Object invoke_S3(Object av) throws Throwable { av = super.check(av, 3);
       
   459             return target.invokeExact(
       
   460                 super.select(av,0), super.select(av,1), super.select(av,2)); }
       
   461     }
       
   462     static class S4 extends Adapter {
       
   463         protected S4(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   464         protected S4(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   465         protected S4 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S4(outer, t); }
       
   466         protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 0);
       
   467             return target.invokeExact(a0, a1, a2, a3); }
       
   468         protected Object invoke_S1(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 1);
       
   469             return target.invokeExact(a0, a1, a2,
       
   470                 super.select(av,0)); }
       
   471         protected Object invoke_S2(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 2);
       
   472             return target.invokeExact(a0, a1,
       
   473                 super.select(av,0), super.select(av,1)); }
       
   474         protected Object invoke_S3(Object a0, Object av) throws Throwable { av = super.check(av, 3);
       
   475             return target.invokeExact(a0,
       
   476                 super.select(av,0), super.select(av,1), super.select(av,2)); }
       
   477         protected Object invoke_S4(Object av) throws Throwable { av = super.check(av, 4);
       
   478             return target.invokeExact(
       
   479                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
       
   480     }
       
   481     static class S5 extends Adapter {
       
   482         protected S5(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   483         protected S5(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   484         protected S5 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S5(outer, t); }
       
   485         protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 0);
       
   486             return target.invokeExact(a0, a1, a2, a3, a4); }
       
   487         protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 1);
       
   488             return target.invokeExact(a0, a1, a2, a3,
       
   489                 super.select(av,0)); }
       
   490         protected Object invoke_S2(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 2);
       
   491             return target.invokeExact(a0, a1, a2,
       
   492                 super.select(av,0), super.select(av,1)); }
       
   493         protected Object invoke_S3(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 3);
       
   494             return target.invokeExact(a0, a1,
       
   495                 super.select(av,0), super.select(av,1), super.select(av,2)); }
       
   496         protected Object invoke_S4(Object a0, Object av) throws Throwable { av = super.check(av, 4);
       
   497             return target.invokeExact(a0,
       
   498                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
       
   499         protected Object invoke_S5(Object av) throws Throwable { av = super.check(av, 5);
       
   500             return target.invokeExact(
       
   501                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   502                 super.select(av,4)); }
       
   503     }
       
   504     static class S6 extends Adapter {
       
   505         protected S6(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   506         protected S6(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   507         protected S6 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S6(outer, t); }
       
   508         protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 0);
       
   509             return target.invokeExact(a0, a1, a2, a3, a4, a5); }
       
   510         protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 1);
       
   511             return target.invokeExact(a0, a1, a2, a3, a4,
       
   512                 super.select(av,0)); }
       
   513         protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 2);
       
   514             return target.invokeExact(a0, a1, a2, a3,
       
   515                 super.select(av,0), super.select(av,1)); }
       
   516         protected Object invoke_S3(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 3);
       
   517             return target.invokeExact(a0, a1, a2,
       
   518                 super.select(av,0), super.select(av,1), super.select(av,2)); }
       
   519         protected Object invoke_S4(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 4);
       
   520             return target.invokeExact(a0, a1,
       
   521                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
       
   522         protected Object invoke_S5(Object a0, Object av) throws Throwable { av = super.check(av, 5);
       
   523             return target.invokeExact(a0,
       
   524                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   525                 super.select(av,4)); }
       
   526         protected Object invoke_S6(Object av) throws Throwable { av = super.check(av, 6);
       
   527             return target.invokeExact(
       
   528                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   529                 super.select(av,4), super.select(av,5)); }
       
   530     }
       
   531     static class S7 extends Adapter {
       
   532         protected S7(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   533         protected S7(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   534         protected S7 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S7(outer, t); }
       
   535         protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 0);
       
   536             return target.invokeExact(a0, a1, a2, a3, a4, a5, a6); }
       
   537         protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 1);
       
   538             return target.invokeExact(a0, a1, a2, a3, a4, a5,
       
   539                 super.select(av,0)); }
       
   540         protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 2);
       
   541             return target.invokeExact(a0, a1, a2, a3, a4,
       
   542                 super.select(av,0), super.select(av,1)); }
       
   543         protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 3);
       
   544             return target.invokeExact(a0, a1, a2, a3,
       
   545                 super.select(av,0), super.select(av,1), super.select(av,2)); }
       
   546         protected Object invoke_S4(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 4);
       
   547             return target.invokeExact(a0, a1, a2,
       
   548                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
       
   549         protected Object invoke_S5(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 5);
       
   550             return target.invokeExact(a0, a1,
       
   551                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   552                 super.select(av,4)); }
       
   553         protected Object invoke_S6(Object a0, Object av) throws Throwable { av = super.check(av, 6);
       
   554             return target.invokeExact(a0,
       
   555                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   556                 super.select(av,4), super.select(av,5)); }
       
   557         protected Object invoke_S7(Object av) throws Throwable { av = super.check(av, 7);
       
   558             return target.invokeExact(
       
   559                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   560                 super.select(av,4), super.select(av,5), super.select(av,6)); }
       
   561     }
       
   562     static class S8 extends Adapter {
       
   563         protected S8(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   564         protected S8(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   565         protected S8 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S8(outer, t); }
       
   566         protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 0);
       
   567             return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7); }
       
   568         protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 1);
       
   569             return target.invokeExact(a0, a1, a2, a3, a4, a5, a6,
       
   570                 super.select(av,0)); }
       
   571         protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 2);
       
   572             return target.invokeExact(a0, a1, a2, a3, a4, a5,
       
   573                 super.select(av,0), super.select(av,1)); }
       
   574         protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 3);
       
   575             return target.invokeExact(a0, a1, a2, a3, a4,
       
   576                 super.select(av,0), super.select(av,1), super.select(av,2)); }
       
   577         protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 4);
       
   578             return target.invokeExact(a0, a1, a2, a3,
       
   579                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
       
   580         protected Object invoke_S5(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 5);
       
   581             return target.invokeExact(a0, a1, a2,
       
   582                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   583                 super.select(av,4)); }
       
   584         protected Object invoke_S6(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 6);
       
   585             return target.invokeExact(a0, a1,
       
   586                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   587                 super.select(av,4), super.select(av,5)); }
       
   588         protected Object invoke_S7(Object a0, Object av) throws Throwable { av = super.check(av, 7);
       
   589             return target.invokeExact(a0,
       
   590                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   591                 super.select(av,4), super.select(av,5), super.select(av,6)); }
       
   592         protected Object invoke_S8(Object av) throws Throwable { av = super.check(av, 8);
       
   593             return target.invokeExact(
       
   594                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   595                 super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
       
   596     }
       
   597     static class S9 extends Adapter {
       
   598         protected S9(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   599         protected S9(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   600         protected S9 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S9(outer, t); }
       
   601         protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object av) throws Throwable { av = super.check(av, 0);
       
   602             return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
       
   603         protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 1);
       
   604             return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7,
       
   605                 super.select(av,0)); }
       
   606         protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 2);
       
   607             return target.invokeExact(a0, a1, a2, a3, a4, a5, a6,
       
   608                 super.select(av,0), super.select(av,1)); }
       
   609         protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 3);
       
   610             return target.invokeExact(a0, a1, a2, a3, a4, a5,
       
   611                 super.select(av,0), super.select(av,1), super.select(av,2)); }
       
   612         protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 4);
       
   613             return target.invokeExact(a0, a1, a2, a3, a4,
       
   614                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
       
   615         protected Object invoke_S5(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 5);
       
   616             return target.invokeExact(a0, a1, a2, a3,
       
   617                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   618                 super.select(av,4)); }
       
   619         protected Object invoke_S6(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 6);
       
   620             return target.invokeExact(a0, a1, a2,
       
   621                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   622                 super.select(av,4), super.select(av,5)); }
       
   623         protected Object invoke_S7(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 7);
       
   624             return target.invokeExact(a0, a1,
       
   625                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   626                 super.select(av,4), super.select(av,5), super.select(av,6)); }
       
   627         protected Object invoke_S8(Object a0, Object av) throws Throwable { av = super.check(av, 8);
       
   628             return target.invokeExact(a0,
       
   629                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   630                 super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
       
   631         protected Object invoke_S9(Object av) throws Throwable { av = super.check(av, 9);
       
   632             return target.invokeExact(
       
   633                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   634                 super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
       
   635                 super.select(av,8)); }
       
   636     }
       
   637     static class S10 extends Adapter {
       
   638         protected S10(SpreadGeneric outer) { super(outer); }  // to build prototype
       
   639         protected S10(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
       
   640         protected S10 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S10(outer, t); }
       
   641         protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9, Object av) throws Throwable { av = super.check(av, 0);
       
   642             return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
       
   643         protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object av) throws Throwable { av = super.check(av, 1);
       
   644             return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8,
       
   645                 super.select(av,0)); }
       
   646         protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 2);
       
   647             return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7,
       
   648                 super.select(av,0), super.select(av,1)); }
       
   649         protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 3);
       
   650             return target.invokeExact(a0, a1, a2, a3, a4, a5, a6,
       
   651                 super.select(av,0), super.select(av,1), super.select(av,2)); }
       
   652         protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 4);
       
   653             return target.invokeExact(a0, a1, a2, a3, a4, a5,
       
   654                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
       
   655         protected Object invoke_S5(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 5);
       
   656             return target.invokeExact(a0, a1, a2, a3, a4,
       
   657                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   658                 super.select(av,4)); }
       
   659         protected Object invoke_S6(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 6);
       
   660             return target.invokeExact(a0, a1, a2, a3,
       
   661                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   662                 super.select(av,4), super.select(av,5)); }
       
   663         protected Object invoke_S7(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 7);
       
   664             return target.invokeExact(a0, a1, a2,
       
   665                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   666                 super.select(av,4), super.select(av,5), super.select(av,6)); }
       
   667         protected Object invoke_S8(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 8);
       
   668             return target.invokeExact(a0, a1,
       
   669                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   670                 super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
       
   671         protected Object invoke_S9(Object a0, Object av) throws Throwable { av = super.check(av, 9);
       
   672             return target.invokeExact(a0,
       
   673                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   674                 super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
       
   675                 super.select(av,8)); }
       
   676         protected Object invoke_S10(Object av) throws Throwable { av = super.check(av, 10);
       
   677             return target.invokeExact(
       
   678                 super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
       
   679                 super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
       
   680                 super.select(av,8), super.select(av,9)); }
       
   681     }
       
   682 }