100 }
101 /*non-public*/
102 BoundMethodHandle bindArgumentJ(int pos, long value) {
103 MethodType type = type().dropParameterTypes(pos, pos+1);
104 LambdaForm form = internalForm().bind(1+pos, speciesData());
105 return copyWithExtendJ(type, form, value);
106 }
107 /*non-public*/
108 BoundMethodHandle bindArgumentF(int pos, float value) {
109 MethodType type = type().dropParameterTypes(pos, pos+1);
110 LambdaForm form = internalForm().bind(1+pos, speciesData());
111 return copyWithExtendF(type, form, value);
112 }
113 /*non-public*/
114 BoundMethodHandle bindArgumentD(int pos, double value) {
115 MethodType type = type().dropParameterTypes(pos, pos + 1);
116 LambdaForm form = internalForm().bind(1+pos, speciesData());
117 return copyWithExtendD(type, form, value);
118 }
119
120 /**
121 * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a
122 * static field containing this value, and they must accordingly implement this method.
123 */
124 /*non-public*/ abstract SpeciesData speciesData();
125
126 /**
127 * Return the number of fields in this BMH. Equivalent to speciesData().fieldCount().
128 */
129 /*non-public*/ abstract int fieldCount();
130
131 @Override
132 Object internalProperties() {
133 return "\n& BMH="+internalValues();
134 }
135
136 @Override
137 final Object internalValues() {
138 Object[] boundValues = new Object[speciesData().fieldCount()];
139 for (int i = 0; i < boundValues.length; ++i) {
151 case F_TYPE: return (float) speciesData().getters[i].invokeBasic(this);
152 case D_TYPE: return (double) speciesData().getters[i].invokeBasic(this);
153 }
154 } catch (Throwable ex) {
155 throw newInternalError(ex);
156 }
157 throw new InternalError("unexpected type: " + speciesData().typeChars+"."+i);
158 }
159
160 //
161 // cloning API
162 //
163
164 /*non-public*/ abstract BoundMethodHandle copyWith(MethodType mt, LambdaForm lf);
165 /*non-public*/ abstract BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg);
166 /*non-public*/ abstract BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg);
167 /*non-public*/ abstract BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg);
168 /*non-public*/ abstract BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg);
169 /*non-public*/ abstract BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg);
170
171 // The following is a grossly irregular hack:
172 @Override MethodHandle reinvokerTarget() {
173 try {
174 return (MethodHandle) arg(0);
175 } catch (Throwable ex) {
176 throw newInternalError(ex);
177 }
178 }
179
180 //
181 // concrete BMH classes required to close bootstrap loops
182 //
183
184 private // make it private to force users to access the enclosing class first
185 static final class Species_L extends BoundMethodHandle {
186 final Object argL0;
187 private Species_L(MethodType mt, LambdaForm lf, Object argL0) {
188 super(mt, lf);
189 this.argL0 = argL0;
190 }
191 // The following is a grossly irregular hack:
192 @Override MethodHandle reinvokerTarget() { return (MethodHandle) argL0; }
193 @Override
194 /*non-public*/ SpeciesData speciesData() {
195 return SPECIES_DATA;
196 }
197 @Override
198 /*non-public*/ int fieldCount() {
199 return 1;
200 }
201 /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
202 /*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) {
203 return new Species_L(mt, lf, argL0);
204 }
205 @Override
206 /*non-public*/ final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
207 return new Species_L(mt, lf, argL0);
208 }
209 @Override
210 /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
211 try {
212 return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
552 mv.visitVarInsn(ALOAD, 1); // type
553 mv.visitVarInsn(ALOAD, 2); // form
554
555 mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true), false);
556
557 for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
558 // i counts the arguments, j counts corresponding argument slots
559 char t = types.charAt(i);
560 mv.visitVarInsn(ALOAD, 0);
561 mv.visitVarInsn(typeLoadOp(t), j + 3); // parameters start at 3
562 mv.visitFieldInsn(PUTFIELD, className, makeFieldName(types, i), typeSig(t));
563 if (t == 'J' || t == 'D') {
564 ++j; // adjust argument register access
565 }
566 }
567
568 mv.visitInsn(RETURN);
569 mv.visitMaxs(0, 0);
570 mv.visitEnd();
571
572 // emit implementation of reinvokerTarget()
573 mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "reinvokerTarget", "()" + MH_SIG, null, null);
574 mv.visitCode();
575 mv.visitVarInsn(ALOAD, 0);
576 mv.visitFieldInsn(GETFIELD, className, "argL0", JLO_SIG);
577 mv.visitTypeInsn(CHECKCAST, MH);
578 mv.visitInsn(ARETURN);
579 mv.visitMaxs(0, 0);
580 mv.visitEnd();
581
582 // emit implementation of speciesData()
583 mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
584 mv.visitCode();
585 mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
586 mv.visitInsn(ARETURN);
587 mv.visitMaxs(0, 0);
588 mv.visitEnd();
589
590 // emit implementation of fieldCount()
591 mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "fieldCount", INT_SIG, null, null);
592 mv.visitCode();
593 int fc = types.length();
594 if (fc <= (ICONST_5 - ICONST_0)) {
595 mv.visitInsn(ICONST_0 + fc);
596 } else {
597 mv.visitIntInsn(SIPUSH, fc);
598 }
599 mv.visitInsn(IRETURN);
600 mv.visitMaxs(0, 0);
601 mv.visitEnd();
|
100 }
101 /*non-public*/
102 BoundMethodHandle bindArgumentJ(int pos, long value) {
103 MethodType type = type().dropParameterTypes(pos, pos+1);
104 LambdaForm form = internalForm().bind(1+pos, speciesData());
105 return copyWithExtendJ(type, form, value);
106 }
107 /*non-public*/
108 BoundMethodHandle bindArgumentF(int pos, float value) {
109 MethodType type = type().dropParameterTypes(pos, pos+1);
110 LambdaForm form = internalForm().bind(1+pos, speciesData());
111 return copyWithExtendF(type, form, value);
112 }
113 /*non-public*/
114 BoundMethodHandle bindArgumentD(int pos, double value) {
115 MethodType type = type().dropParameterTypes(pos, pos + 1);
116 LambdaForm form = internalForm().bind(1+pos, speciesData());
117 return copyWithExtendD(type, form, value);
118 }
119
120 @Override
121 BoundMethodHandle rebind() {
122 if (!tooComplex()) {
123 return this;
124 }
125 return makeReinvoker(this);
126 }
127
128 private boolean tooComplex() {
129 return (fieldCount() > FIELD_COUNT_THRESHOLD ||
130 form.expressionCount() > FORM_EXPRESSION_THRESHOLD);
131 }
132 private static int FIELD_COUNT_THRESHOLD = 12; // largest convenient BMH field count
133 private static int FORM_EXPRESSION_THRESHOLD = 24; // largest convenient BMH expression count
134
135 /**
136 * A reinvoker MH has this form:
137 * {@code lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) }}
138 */
139 static BoundMethodHandle makeReinvoker(MethodHandle target) {
140 LambdaForm form = DelegatingMethodHandle.makeReinvokerForm(
141 target, MethodTypeForm.LF_REBIND, Species_L.SPECIES_DATA.getterFunction(0) );
142 return Species_L.make(target.type(), form, target);
143 }
144
145 /**
146 * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a
147 * static field containing this value, and they must accordingly implement this method.
148 */
149 /*non-public*/ abstract SpeciesData speciesData();
150
151 /**
152 * Return the number of fields in this BMH. Equivalent to speciesData().fieldCount().
153 */
154 /*non-public*/ abstract int fieldCount();
155
156 @Override
157 Object internalProperties() {
158 return "\n& BMH="+internalValues();
159 }
160
161 @Override
162 final Object internalValues() {
163 Object[] boundValues = new Object[speciesData().fieldCount()];
164 for (int i = 0; i < boundValues.length; ++i) {
176 case F_TYPE: return (float) speciesData().getters[i].invokeBasic(this);
177 case D_TYPE: return (double) speciesData().getters[i].invokeBasic(this);
178 }
179 } catch (Throwable ex) {
180 throw newInternalError(ex);
181 }
182 throw new InternalError("unexpected type: " + speciesData().typeChars+"."+i);
183 }
184
185 //
186 // cloning API
187 //
188
189 /*non-public*/ abstract BoundMethodHandle copyWith(MethodType mt, LambdaForm lf);
190 /*non-public*/ abstract BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg);
191 /*non-public*/ abstract BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg);
192 /*non-public*/ abstract BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg);
193 /*non-public*/ abstract BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg);
194 /*non-public*/ abstract BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg);
195
196 //
197 // concrete BMH classes required to close bootstrap loops
198 //
199
200 private // make it private to force users to access the enclosing class first
201 static final class Species_L extends BoundMethodHandle {
202 final Object argL0;
203 private Species_L(MethodType mt, LambdaForm lf, Object argL0) {
204 super(mt, lf);
205 this.argL0 = argL0;
206 }
207 @Override
208 /*non-public*/ SpeciesData speciesData() {
209 return SPECIES_DATA;
210 }
211 @Override
212 /*non-public*/ int fieldCount() {
213 return 1;
214 }
215 /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
216 /*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) {
217 return new Species_L(mt, lf, argL0);
218 }
219 @Override
220 /*non-public*/ final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
221 return new Species_L(mt, lf, argL0);
222 }
223 @Override
224 /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
225 try {
226 return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
566 mv.visitVarInsn(ALOAD, 1); // type
567 mv.visitVarInsn(ALOAD, 2); // form
568
569 mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true), false);
570
571 for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
572 // i counts the arguments, j counts corresponding argument slots
573 char t = types.charAt(i);
574 mv.visitVarInsn(ALOAD, 0);
575 mv.visitVarInsn(typeLoadOp(t), j + 3); // parameters start at 3
576 mv.visitFieldInsn(PUTFIELD, className, makeFieldName(types, i), typeSig(t));
577 if (t == 'J' || t == 'D') {
578 ++j; // adjust argument register access
579 }
580 }
581
582 mv.visitInsn(RETURN);
583 mv.visitMaxs(0, 0);
584 mv.visitEnd();
585
586 // emit implementation of speciesData()
587 mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
588 mv.visitCode();
589 mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
590 mv.visitInsn(ARETURN);
591 mv.visitMaxs(0, 0);
592 mv.visitEnd();
593
594 // emit implementation of fieldCount()
595 mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "fieldCount", INT_SIG, null, null);
596 mv.visitCode();
597 int fc = types.length();
598 if (fc <= (ICONST_5 - ICONST_0)) {
599 mv.visitInsn(ICONST_0 + fc);
600 } else {
601 mv.visitIntInsn(SIPUSH, fc);
602 }
603 mv.visitInsn(IRETURN);
604 mv.visitMaxs(0, 0);
605 mv.visitEnd();
|