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 (NoAccessException 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 }