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