src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java
changeset 59201 b24f4caa1411
parent 47753 a2008587c13f
equal deleted inserted replaced
59200:a686b67a59d9 59201:b24f4caa1411
    46  * on a predetermined argument.  The JVM dispatches to the correct method
    46  * on a predetermined argument.  The JVM dispatches to the correct method
    47  * when the handle is created, not when it is invoked.
    47  * when the handle is created, not when it is invoked.
    48  *
    48  *
    49  * All bound arguments are encapsulated in dedicated species.
    49  * All bound arguments are encapsulated in dedicated species.
    50  */
    50  */
    51 /*non-public*/ abstract class BoundMethodHandle extends MethodHandle {
    51 /*non-public*/
    52 
    52 abstract class BoundMethodHandle extends MethodHandle {
    53     /*non-public*/ BoundMethodHandle(MethodType type, LambdaForm form) {
    53 
       
    54     /*non-public*/
       
    55     BoundMethodHandle(MethodType type, LambdaForm form) {
    54         super(type, form);
    56         super(type, form);
    55         assert(speciesData() == speciesDataFor(form));
    57         assert(speciesData() == speciesDataFor(form));
    56     }
    58     }
    57 
    59 
    58     //
    60     //
   139 
   141 
   140     /**
   142     /**
   141      * Return the {@link BoundMethodHandle.SpeciesData} instance representing this BMH species. All subclasses must provide a
   143      * Return the {@link BoundMethodHandle.SpeciesData} instance representing this BMH species. All subclasses must provide a
   142      * static field containing this value, and they must accordingly implement this method.
   144      * static field containing this value, and they must accordingly implement this method.
   143      */
   145      */
   144     /*non-public*/ abstract BoundMethodHandle.SpeciesData speciesData();
   146     /*non-public*/
   145 
   147     abstract BoundMethodHandle.SpeciesData speciesData();
   146     /*non-public*/ static BoundMethodHandle.SpeciesData speciesDataFor(LambdaForm form) {
   148 
       
   149     /*non-public*/
       
   150     static BoundMethodHandle.SpeciesData speciesDataFor(LambdaForm form) {
   147         Object c = form.names[0].constraint;
   151         Object c = form.names[0].constraint;
   148         if (c instanceof SpeciesData) {
   152         if (c instanceof SpeciesData) {
   149             return (SpeciesData) c;
   153             return (SpeciesData) c;
   150         }
   154         }
   151         // if there is no BMH constraint, then use the null constraint
   155         // if there is no BMH constraint, then use the null constraint
   153     }
   157     }
   154 
   158 
   155     /**
   159     /**
   156      * Return the number of fields in this BMH.  Equivalent to speciesData().fieldCount().
   160      * Return the number of fields in this BMH.  Equivalent to speciesData().fieldCount().
   157      */
   161      */
   158     /*non-public*/ final int fieldCount() { return speciesData().fieldCount(); }
   162     /*non-public*/
       
   163     final int fieldCount() { return speciesData().fieldCount(); }
   159 
   164 
   160     @Override
   165     @Override
   161     Object internalProperties() {
   166     Object internalProperties() {
   162         return "\n& BMH="+internalValues();
   167         return "\n& BMH="+internalValues();
   163     }
   168     }
   173             sb.append("\n  ").append(i).append(": ( ").append(arg(i)).append(" )");
   178             sb.append("\n  ").append(i).append(": ( ").append(arg(i)).append(" )");
   174         }
   179         }
   175         return sb.append("\n]").toString();
   180         return sb.append("\n]").toString();
   176     }
   181     }
   177 
   182 
   178     /*non-public*/ final Object arg(int i) {
   183     /*non-public*/
       
   184     final Object arg(int i) {
   179         try {
   185         try {
   180             Class<?> fieldType = speciesData().fieldTypes().get(i);
   186             Class<?> fieldType = speciesData().fieldTypes().get(i);
   181             switch (BasicType.basicType(fieldType)) {
   187             switch (BasicType.basicType(fieldType)) {
   182                 case L_TYPE: return          speciesData().getter(i).invokeBasic(this);
   188                 case L_TYPE: return          speciesData().getter(i).invokeBasic(this);
   183                 case I_TYPE: return (int)    speciesData().getter(i).invokeBasic(this);
   189                 case I_TYPE: return (int)    speciesData().getter(i).invokeBasic(this);
   193 
   199 
   194     //
   200     //
   195     // cloning API
   201     // cloning API
   196     //
   202     //
   197 
   203 
   198     /*non-public*/ abstract BoundMethodHandle copyWith(MethodType mt, LambdaForm lf);
   204     /*non-public*/
   199     /*non-public*/ abstract BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg);
   205     abstract BoundMethodHandle copyWith(MethodType mt, LambdaForm lf);
   200     /*non-public*/ abstract BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int    narg);
   206     /*non-public*/
   201     /*non-public*/ abstract BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long   narg);
   207     abstract BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg);
   202     /*non-public*/ abstract BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float  narg);
   208     /*non-public*/
   203     /*non-public*/ abstract BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg);
   209     abstract BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int    narg);
       
   210     /*non-public*/
       
   211     abstract BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long   narg);
       
   212     /*non-public*/
       
   213     abstract BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float  narg);
       
   214     /*non-public*/
       
   215     abstract BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg);
   204 
   216 
   205     //
   217     //
   206     // concrete BMH classes required to close bootstrap loops
   218     // concrete BMH classes required to close bootstrap loops
   207     //
   219     //
   208 
   220 
   215             super(mt, lf);
   227             super(mt, lf);
   216             this.argL0 = argL0;
   228             this.argL0 = argL0;
   217         }
   229         }
   218 
   230 
   219         @Override
   231         @Override
   220         /*non-public*/ SpeciesData speciesData() {
   232         /*non-public*/
       
   233         SpeciesData speciesData() {
   221             return BMH_SPECIES;
   234             return BMH_SPECIES;
   222         }
   235         }
   223 
   236 
   224         /*non-public*/ static @Stable SpeciesData BMH_SPECIES;
   237         /*non-public*/
   225 
   238         static @Stable SpeciesData BMH_SPECIES;
   226         /*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) {
   239 
       
   240         /*non-public*/
       
   241         static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) {
   227             return new Species_L(mt, lf, argL0);
   242             return new Species_L(mt, lf, argL0);
   228         }
   243         }
   229         @Override
   244         @Override
   230         /*non-public*/ final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
   245         /*non-public*/
       
   246         final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
   231             return new Species_L(mt, lf, argL0);
   247             return new Species_L(mt, lf, argL0);
   232         }
   248         }
   233         @Override
   249         @Override
   234         /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
   250         /*non-public*/
       
   251         final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
   235             try {
   252             try {
   236                 return (BoundMethodHandle) BMH_SPECIES.extendWith(L_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
   253                 return (BoundMethodHandle) BMH_SPECIES.extendWith(L_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
   237             } catch (Throwable ex) {
   254             } catch (Throwable ex) {
   238                 throw uncaughtException(ex);
   255                 throw uncaughtException(ex);
   239             }
   256             }
   240         }
   257         }
   241         @Override
   258         @Override
   242         /*non-public*/ final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
   259         /*non-public*/
       
   260         final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
   243             try {
   261             try {
   244                 return (BoundMethodHandle) BMH_SPECIES.extendWith(I_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
   262                 return (BoundMethodHandle) BMH_SPECIES.extendWith(I_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
   245             } catch (Throwable ex) {
   263             } catch (Throwable ex) {
   246                 throw uncaughtException(ex);
   264                 throw uncaughtException(ex);
   247             }
   265             }
   248         }
   266         }
   249         @Override
   267         @Override
   250         /*non-public*/ final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
   268         /*non-public*/
       
   269         final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
   251             try {
   270             try {
   252                 return (BoundMethodHandle) BMH_SPECIES.extendWith(J_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
   271                 return (BoundMethodHandle) BMH_SPECIES.extendWith(J_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
   253             } catch (Throwable ex) {
   272             } catch (Throwable ex) {
   254                 throw uncaughtException(ex);
   273                 throw uncaughtException(ex);
   255             }
   274             }
   256         }
   275         }
   257         @Override
   276         @Override
   258         /*non-public*/ final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
   277         /*non-public*/
       
   278         final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
   259             try {
   279             try {
   260                 return (BoundMethodHandle) BMH_SPECIES.extendWith(F_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
   280                 return (BoundMethodHandle) BMH_SPECIES.extendWith(F_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
   261             } catch (Throwable ex) {
   281             } catch (Throwable ex) {
   262                 throw uncaughtException(ex);
   282                 throw uncaughtException(ex);
   263             }
   283             }
   264         }
   284         }
   265         @Override
   285         @Override
   266         /*non-public*/ final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
   286         /*non-public*/
       
   287         final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
   267             try {
   288             try {
   268                 return (BoundMethodHandle) BMH_SPECIES.extendWith(D_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
   289                 return (BoundMethodHandle) BMH_SPECIES.extendWith(D_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
   269             } catch (Throwable ex) {
   290             } catch (Throwable ex) {
   270                 throw uncaughtException(ex);
   291                 throw uncaughtException(ex);
   271             }
   292             }
   275     //
   296     //
   276     // BMH species meta-data
   297     // BMH species meta-data
   277     //
   298     //
   278 
   299 
   279     /*non-public*/
   300     /*non-public*/
   280     static final class SpeciesData extends ClassSpecializer<BoundMethodHandle, String, SpeciesData>.SpeciesData {
   301     static final class SpeciesData
       
   302             extends ClassSpecializer<BoundMethodHandle, String, SpeciesData>.SpeciesData {
   281         // This array is filled in lazily, as new species come into being over time.
   303         // This array is filled in lazily, as new species come into being over time.
   282         @Stable final private SpeciesData[] extensions = new SpeciesData[ARG_TYPE_LIMIT];
   304         @Stable final private SpeciesData[] extensions = new SpeciesData[ARG_TYPE_LIMIT];
   283 
   305 
   284         public SpeciesData(Specializer outer, String key) {
   306         public SpeciesData(Specializer outer, String key) {
   285             outer.super(key);
   307             outer.super(key);
   344                 return false;
   366                 return false;
   345             }
   367             }
   346             return true;
   368             return true;
   347         }
   369         }
   348 
   370 
   349         /*non-public*/ SpeciesData extendWith(byte typeNum) {
   371         /*non-public*/
       
   372         SpeciesData extendWith(byte typeNum) {
   350             SpeciesData sd = extensions[typeNum];
   373             SpeciesData sd = extensions[typeNum];
   351             if (sd != null)  return sd;
   374             if (sd != null)  return sd;
   352             sd = SPECIALIZER.findSpecies(key() + BasicType.basicType(typeNum).basicTypeChar());
   375             sd = SPECIALIZER.findSpecies(key() + BasicType.basicType(typeNum).basicTypeChar());
   353             extensions[typeNum] = sd;
   376             extensions[typeNum] = sd;
   354             return sd;
   377             return sd;
   361         SimpleMethodHandle.BMH_SPECIES = BoundMethodHandle.SPECIALIZER.findSpecies("");
   384         SimpleMethodHandle.BMH_SPECIES = BoundMethodHandle.SPECIALIZER.findSpecies("");
   362         Species_L.BMH_SPECIES = BoundMethodHandle.SPECIALIZER.findSpecies("L");
   385         Species_L.BMH_SPECIES = BoundMethodHandle.SPECIALIZER.findSpecies("L");
   363     }
   386     }
   364 
   387 
   365     /*non-public*/
   388     /*non-public*/
   366     static final class Specializer extends ClassSpecializer<BoundMethodHandle, String, SpeciesData> {
   389     static final class Specializer
       
   390             extends ClassSpecializer<BoundMethodHandle, String, SpeciesData> {
   367 
   391 
   368         private static final MemberName SPECIES_DATA_ACCESSOR;
   392         private static final MemberName SPECIES_DATA_ACCESSOR;
   369 
   393 
   370         static {
   394         static {
   371             try {
   395             try {