jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java
changeset 23918 5f40f1d88890
parent 23038 bb8b3b23af3a
child 24572 5c9e5961d21c
equal deleted inserted replaced
23917:d247e52b5262 23918:5f40f1d88890
   138 
   138 
   139     /**
   139     /**
   140      * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a
   140      * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a
   141      * static field containing this value, and they must accordingly implement this method.
   141      * static field containing this value, and they must accordingly implement this method.
   142      */
   142      */
   143     protected abstract SpeciesData speciesData();
   143     /*non-public*/ abstract SpeciesData speciesData();
   144 
   144 
   145     @Override
   145     @Override
   146     final Object internalProperties() {
   146     final Object internalProperties() {
   147         return "/BMH="+internalValues();
   147         return "/BMH="+internalValues();
   148     }
   148     }
   154             boundValues[i] = arg(i);
   154             boundValues[i] = arg(i);
   155         }
   155         }
   156         return Arrays.asList(boundValues);
   156         return Arrays.asList(boundValues);
   157     }
   157     }
   158 
   158 
   159     public final Object arg(int i) {
   159     /*non-public*/ final Object arg(int i) {
   160         try {
   160         try {
   161             switch (speciesData().fieldType(i)) {
   161             switch (speciesData().fieldType(i)) {
   162             case 'L': return argL(i);
   162             case 'L': return argL(i);
   163             case 'I': return argI(i);
   163             case 'I': return argI(i);
   164             case 'F': return argF(i);
   164             case 'F': return argF(i);
   168         } catch (Throwable ex) {
   168         } catch (Throwable ex) {
   169             throw newInternalError(ex);
   169             throw newInternalError(ex);
   170         }
   170         }
   171         throw new InternalError("unexpected type: " + speciesData().types+"."+i);
   171         throw new InternalError("unexpected type: " + speciesData().types+"."+i);
   172     }
   172     }
   173     public final Object argL(int i) throws Throwable { return          speciesData().getters[i].invokeBasic(this); }
   173     /*non-public*/ final Object argL(int i) throws Throwable { return          speciesData().getters[i].invokeBasic(this); }
   174     public final int    argI(int i) throws Throwable { return (int)    speciesData().getters[i].invokeBasic(this); }
   174     /*non-public*/ final int    argI(int i) throws Throwable { return (int)    speciesData().getters[i].invokeBasic(this); }
   175     public final float  argF(int i) throws Throwable { return (float)  speciesData().getters[i].invokeBasic(this); }
   175     /*non-public*/ final float  argF(int i) throws Throwable { return (float)  speciesData().getters[i].invokeBasic(this); }
   176     public final double argD(int i) throws Throwable { return (double) speciesData().getters[i].invokeBasic(this); }
   176     /*non-public*/ final double argD(int i) throws Throwable { return (double) speciesData().getters[i].invokeBasic(this); }
   177     public final long   argJ(int i) throws Throwable { return (long)   speciesData().getters[i].invokeBasic(this); }
   177     /*non-public*/ final long   argJ(int i) throws Throwable { return (long)   speciesData().getters[i].invokeBasic(this); }
   178 
   178 
   179     //
   179     //
   180     // cloning API
   180     // cloning API
   181     //
   181     //
   182 
   182 
   183     public abstract BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable;
   183     /*non-public*/ abstract BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable;
   184     public abstract BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable;
   184     /*non-public*/ abstract BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable;
   185     public abstract BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int    narg) throws Throwable;
   185     /*non-public*/ abstract BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int    narg) throws Throwable;
   186     public abstract BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long   narg) throws Throwable;
   186     /*non-public*/ abstract BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long   narg) throws Throwable;
   187     public abstract BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float  narg) throws Throwable;
   187     /*non-public*/ abstract BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float  narg) throws Throwable;
   188     public abstract BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable;
   188     /*non-public*/ abstract BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable;
   189 
   189 
   190     // The following is a grossly irregular hack:
   190     // The following is a grossly irregular hack:
   191     @Override MethodHandle reinvokerTarget() {
   191     @Override MethodHandle reinvokerTarget() {
   192         try {
   192         try {
   193             return (MethodHandle) argL(0);
   193             return (MethodHandle) argL(0);
   201     //
   201     //
   202 
   202 
   203     private  // make it private to force users to access the enclosing class first
   203     private  // make it private to force users to access the enclosing class first
   204     static final class Species_L extends BoundMethodHandle {
   204     static final class Species_L extends BoundMethodHandle {
   205         final Object argL0;
   205         final Object argL0;
   206         public Species_L(MethodType mt, LambdaForm lf, Object argL0) {
   206         /*non-public*/ Species_L(MethodType mt, LambdaForm lf, Object argL0) {
   207             super(mt, lf);
   207             super(mt, lf);
   208             this.argL0 = argL0;
   208             this.argL0 = argL0;
   209         }
   209         }
   210         // The following is a grossly irregular hack:
   210         // The following is a grossly irregular hack:
   211         @Override MethodHandle reinvokerTarget() { return (MethodHandle) argL0; }
   211         @Override MethodHandle reinvokerTarget() { return (MethodHandle) argL0; }
   212         @Override
   212         @Override
   213         public SpeciesData speciesData() {
   213         /*non-public*/ SpeciesData speciesData() {
   214             return SPECIES_DATA;
   214             return SPECIES_DATA;
   215         }
   215         }
   216         public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
   216         /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
   217         @Override
   217         @Override
   218         public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable {
   218         /*non-public*/ final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable {
   219             return new Species_L(mt, lf, argL0);
   219             return new Species_L(mt, lf, argL0);
   220         }
   220         }
   221         @Override
   221         @Override
   222         public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
   222         /*non-public*/ final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
   223             return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, narg);
   223             return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, narg);
   224         }
   224         }
   225         @Override
   225         @Override
   226         public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable {
   226         /*non-public*/ final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable {
   227             return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, narg);
   227             return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, narg);
   228         }
   228         }
   229         @Override
   229         @Override
   230         public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
   230         /*non-public*/ final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
   231             return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, narg);
   231             return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, narg);
   232         }
   232         }
   233         @Override
   233         @Override
   234         public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable {
   234         /*non-public*/ final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable {
   235             return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, narg);
   235             return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, narg);
   236         }
   236         }
   237         @Override
   237         @Override
   238         public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable {
   238         /*non-public*/ final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable {
   239             return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, narg);
   239             return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, narg);
   240         }
   240         }
   241     }
   241     }
   242 
   242 
   243 /*
   243 /*
   336         // Therefore, we need a non-final link in the chain.  Use array elements.
   336         // Therefore, we need a non-final link in the chain.  Use array elements.
   337         final MethodHandle[]                     constructor;
   337         final MethodHandle[]                     constructor;
   338         final MethodHandle[]                     getters;
   338         final MethodHandle[]                     getters;
   339         final SpeciesData[]                      extensions;
   339         final SpeciesData[]                      extensions;
   340 
   340 
   341         public int fieldCount() {
   341         /*non-public*/ int fieldCount() {
   342             return types.length();
   342             return types.length();
   343         }
   343         }
   344         public char fieldType(int i) {
   344         /*non-public*/ char fieldType(int i) {
   345             return types.charAt(i);
   345             return types.charAt(i);
   346         }
   346         }
   347 
   347 
   348         public String toString() {
   348         public String toString() {
   349             return "SpeciesData["+(isPlaceholder() ? "<placeholder>" : clazz.getSimpleName())+":"+types+"]";
   349             return "SpeciesData["+(isPlaceholder() ? "<placeholder>" : clazz.getSimpleName())+":"+types+"]";
   549          * class BoundMethodHandle { ... private static
   549          * class BoundMethodHandle { ... private static
   550          * final class Species_LLI extends BoundMethodHandle {
   550          * final class Species_LLI extends BoundMethodHandle {
   551          *     final Object argL0;
   551          *     final Object argL0;
   552          *     final Object argL1;
   552          *     final Object argL1;
   553          *     final int argI2;
   553          *     final int argI2;
   554          *     public Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
   554          *     Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
   555          *         super(mt, lf);
   555          *         super(mt, lf);
   556          *         this.argL0 = argL0;
   556          *         this.argL0 = argL0;
   557          *         this.argL1 = argL1;
   557          *         this.argL1 = argL1;
   558          *         this.argI2 = argI2;
   558          *         this.argI2 = argI2;
   559          *     }
   559          *     }
   560          *     public final SpeciesData speciesData() { return SPECIES_DATA; }
   560          *     final SpeciesData speciesData() { return SPECIES_DATA; }
   561          *     public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class);
   561          *     static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class);
   562          *     public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) {
   562          *     final BoundMethodHandle clone(MethodType mt, LambdaForm lf) {
   563          *         return SPECIES_DATA.constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2);
   563          *         return SPECIES_DATA.constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2);
   564          *     }
   564          *     }
   565          *     public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) {
   565          *     final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) {
   566          *         return SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   566          *         return SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   567          *     }
   567          *     }
   568          *     public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) {
   568          *     final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) {
   569          *         return SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   569          *         return SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   570          *     }
   570          *     }
   571          *     public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) {
   571          *     final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) {
   572          *         return SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   572          *         return SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   573          *     }
   573          *     }
   574          *     public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) {
   574          *     final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) {
   575          *         return SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   575          *         return SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   576          *     }
   576          *     }
   577          *     public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) {
   577          *     final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) {
   578          *         return SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   578          *         return SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   579          *     }
   579          *     }
   580          * }
   580          * }
   581          * </pre>
   581          * </pre>
   582          *
   582          *
   586         static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String types) {
   586         static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String types) {
   587             final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
   587             final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
   588 
   588 
   589             final String className  = SPECIES_PREFIX_PATH + types;
   589             final String className  = SPECIES_PREFIX_PATH + types;
   590             final String sourceFile = SPECIES_PREFIX_NAME + types;
   590             final String sourceFile = SPECIES_PREFIX_NAME + types;
   591             cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null);
   591             final int NOT_ACC_PUBLIC = 0;  // not ACC_PUBLIC
       
   592             cw.visit(V1_6, NOT_ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null);
   592             cw.visitSource(sourceFile, null);
   593             cw.visitSource(sourceFile, null);
   593 
   594 
   594             // emit static types and SPECIES_DATA fields
   595             // emit static types and SPECIES_DATA fields
   595             cw.visitField(ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd();
   596             cw.visitField(NOT_ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd();
   596 
   597 
   597             // emit bound argument fields
   598             // emit bound argument fields
   598             for (int i = 0; i < types.length(); ++i) {
   599             for (int i = 0; i < types.length(); ++i) {
   599                 final char t = types.charAt(i);
   600                 final char t = types.charAt(i);
   600                 final String fieldName = makeFieldName(types, i);
   601                 final String fieldName = makeFieldName(types, i);
   603             }
   604             }
   604 
   605 
   605             MethodVisitor mv;
   606             MethodVisitor mv;
   606 
   607 
   607             // emit constructor
   608             // emit constructor
   608             mv = cw.visitMethod(ACC_PUBLIC, "<init>", makeSignature(types, true), null, null);
   609             mv = cw.visitMethod(NOT_ACC_PUBLIC, "<init>", makeSignature(types, true), null, null);
   609             mv.visitCode();
   610             mv.visitCode();
   610             mv.visitVarInsn(ALOAD, 0);
   611             mv.visitVarInsn(ALOAD, 0);
   611             mv.visitVarInsn(ALOAD, 1);
   612             mv.visitVarInsn(ALOAD, 1);
   612             mv.visitVarInsn(ALOAD, 2);
   613             mv.visitVarInsn(ALOAD, 2);
   613 
   614 
   627             mv.visitInsn(RETURN);
   628             mv.visitInsn(RETURN);
   628             mv.visitMaxs(0, 0);
   629             mv.visitMaxs(0, 0);
   629             mv.visitEnd();
   630             mv.visitEnd();
   630 
   631 
   631             // emit implementation of reinvokerTarget()
   632             // emit implementation of reinvokerTarget()
   632             mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "reinvokerTarget", "()" + MH_SIG, null, null);
   633             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "reinvokerTarget", "()" + MH_SIG, null, null);
   633             mv.visitCode();
   634             mv.visitCode();
   634             mv.visitVarInsn(ALOAD, 0);
   635             mv.visitVarInsn(ALOAD, 0);
   635             mv.visitFieldInsn(GETFIELD, className, "argL0", JLO_SIG);
   636             mv.visitFieldInsn(GETFIELD, className, "argL0", JLO_SIG);
   636             mv.visitTypeInsn(CHECKCAST, MH);
   637             mv.visitTypeInsn(CHECKCAST, MH);
   637             mv.visitInsn(ARETURN);
   638             mv.visitInsn(ARETURN);
   638             mv.visitMaxs(0, 0);
   639             mv.visitMaxs(0, 0);
   639             mv.visitEnd();
   640             mv.visitEnd();
   640 
   641 
   641             // emit implementation of speciesData()
   642             // emit implementation of speciesData()
   642             mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
   643             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
   643             mv.visitCode();
   644             mv.visitCode();
   644             mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
   645             mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
   645             mv.visitInsn(ARETURN);
   646             mv.visitInsn(ARETURN);
   646             mv.visitMaxs(0, 0);
   647             mv.visitMaxs(0, 0);
   647             mv.visitEnd();
   648             mv.visitEnd();
   648 
   649 
   649             // emit clone()
   650             // emit clone()
   650             mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "clone", makeSignature("", false), null, E_THROWABLE);
   651             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "clone", makeSignature("", false), null, E_THROWABLE);
   651             mv.visitCode();
   652             mv.visitCode();
   652             // return speciesData().constructor[0].invokeBasic(mt, lf, argL0, ...)
   653             // return speciesData().constructor[0].invokeBasic(mt, lf, argL0, ...)
   653             // obtain constructor
   654             // obtain constructor
   654             mv.visitVarInsn(ALOAD, 0);
   655             mv.visitVarInsn(ALOAD, 0);
   655             mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
   656             mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
   668             mv.visitEnd();
   669             mv.visitEnd();
   669 
   670 
   670             // for each type, emit cloneExtendT()
   671             // for each type, emit cloneExtendT()
   671             for (Class<?> c : TYPES) {
   672             for (Class<?> c : TYPES) {
   672                 char t = Wrapper.basicTypeChar(c);
   673                 char t = Wrapper.basicTypeChar(c);
   673                 mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "cloneExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE);
   674                 mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "cloneExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE);
   674                 mv.visitCode();
   675                 mv.visitCode();
   675                 // return SPECIES_DATA.extendWithIndex(extensionIndex(t)).constructor[0].invokeBasic(mt, lf, argL0, ..., narg)
   676                 // return SPECIES_DATA.extendWithIndex(extensionIndex(t)).constructor[0].invokeBasic(mt, lf, argL0, ..., narg)
   676                 // obtain constructor
   677                 // obtain constructor
   677                 mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
   678                 mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
   678                 int iconstInsn = ICONST_0 + extensionIndex(t);
   679                 int iconstInsn = ICONST_0 + extensionIndex(t);
   695                 mv.visitMaxs(0, 0);
   696                 mv.visitMaxs(0, 0);
   696                 mv.visitEnd();
   697                 mv.visitEnd();
   697             }
   698             }
   698 
   699 
   699             // emit class initializer
   700             // emit class initializer
   700             mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", VOID_SIG, null, null);
   701             mv = cw.visitMethod(NOT_ACC_PUBLIC | ACC_STATIC, "<clinit>", VOID_SIG, null, null);
   701             mv.visitCode();
   702             mv.visitCode();
   702             mv.visitLdcInsn(types);
   703             mv.visitLdcInsn(types);
   703             mv.visitLdcInsn(Type.getObjectType(className));
   704             mv.visitLdcInsn(Type.getObjectType(className));
   704             mv.visitMethodInsn(INVOKESTATIC, SPECIES_DATA, "getForClass", BMHSPECIES_DATA_GFC_SIG, false);
   705             mv.visitMethodInsn(INVOKESTATIC, SPECIES_DATA, "getForClass", BMHSPECIES_DATA_GFC_SIG, false);
   705             mv.visitFieldInsn(PUTSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
   706             mv.visitFieldInsn(PUTSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);