82 }
83
84 public C getstatic(S owner, CharSequence name, T type) {
85 emitOp(Opcode.GETSTATIC, type);
86 code.writeChar(poolHelper.putFieldRef(owner, name, type));
87 return thisBuilder();
88 }
89
90 public C putstatic(S owner, CharSequence name, T type) {
91 emitOp(Opcode.PUTSTATIC, type);
92 code.writeChar(poolHelper.putFieldRef(owner, name, type));
93 return thisBuilder();
94 }
95
96 public C getfield(S owner, CharSequence name, T type) {
97 emitOp(Opcode.GETFIELD, type);
98 code.writeChar(poolHelper.putFieldRef(owner, name, type));
99 return thisBuilder();
100 }
101
102 public C vgetfield(S owner, CharSequence name, T type) {
103 emitOp(Opcode.VGETFIELD, type);
104 code.writeChar(poolHelper.putFieldRef(owner, name, type));
105 return thisBuilder();
106 }
107
108 public C putfield(S owner, CharSequence name, T type) {
109 emitOp(Opcode.PUTFIELD, type);
110 code.writeChar(poolHelper.putFieldRef(owner, name, type));
111 return thisBuilder();
112 }
113
114 public C invokevirtual(S owner, CharSequence name, T type, boolean isInterface) {
115 emitOp(Opcode.INVOKEVIRTUAL, type);
116 code.writeChar(poolHelper.putMethodRef(owner, name, type, isInterface));
117 return thisBuilder();
118 }
119
120 public C invokespecial(S owner, CharSequence name, T type, boolean isInterface) {
121 emitOp(Opcode.INVOKESPECIAL, type);
122 code.writeChar(poolHelper.putMethodRef(owner, name, type, isInterface));
123 return thisBuilder();
124 }
125
126 public C invokestatic(S owner, CharSequence name, T type, boolean isInterface) {
127 emitOp(Opcode.INVOKESTATIC, type);
128 code.writeChar(poolHelper.putMethodRef(owner, name, type, isInterface));
129 return thisBuilder();
138 nargs += typeHelper.tag(it.next()).width;
139 }
140 code.writeByte(nargs);
141 code.writeByte(0);
142 return thisBuilder();
143 }
144
145 public C invokedynamic(CharSequence invokedName, T invokedType, S bsmClass, CharSequence bsmName, T bsmType, Consumer<StaticArgListBuilder<S, T, E>> staticArgs) {
146 emitOp(Opcode.INVOKEDYNAMIC, invokedType);
147 code.writeChar(poolHelper.putInvokeDynamic(invokedName, invokedType, bsmClass, bsmName, bsmType, staticArgs));
148 code.writeChar(0); //padding
149 return thisBuilder();
150 }
151
152 public C new_(S clazz) {
153 emitOp(Opcode.NEW, clazz);
154 code.writeChar(poolHelper.putClass(clazz));
155 return thisBuilder();
156 }
157
158 public C vnew_(S clazz, CharSequence name, T desc) {
159 emitOp(Opcode.VNEW, clazz);
160 code.writeChar(poolHelper.putMethodRef(clazz, name, desc, false));
161 return thisBuilder();
162 }
163
164 public C vnewarray(S array) {
165 emitOp(Opcode.VNEWARRAY, array);
166 code.writeChar(poolHelper.putClass(array));
167 return thisBuilder();
168 }
169
170 public C newarray(TypeTag tag) {
171 emitOp(Opcode.NEWARRAY, tag);
172 int newarraycode = tag.newarraycode;
173 if (newarraycode == -1) {
174 throw new IllegalStateException("Bad tag " + tag);
175 }
176 code.writeByte(newarraycode);
177 return thisBuilder();
178 }
179
180 public C anewarray(S array) {
181 emitOp(Opcode.ANEWARRAY, array);
182 code.writeChar(poolHelper.putClass(array));
183 return thisBuilder();
184 }
185
186 public C checkcast(S target) {
187 emitOp(Opcode.CHECKCAST);
188 code.writeChar(poolHelper.putClass(target));
189 return thisBuilder();
190 }
191
192 public C instanceof_(S target) {
193 emitOp(Opcode.INSTANCEOF);
194 code.writeChar(poolHelper.putClass(target));
195 return thisBuilder();
196 }
197
198 public C multianewarray(S array, byte dims) {
199 emitOp(Opcode.MULTIANEWARRAY, new Object[]{array, dims});
200 code.writeChar(poolHelper.putClass(array)).writeByte(dims);
201 return thisBuilder();
202 }
203
204 public C multivnewarray(S array, byte dims) {
205 emitOp(Opcode.MULTIVNEWARRAY, new Object[]{array, dims});
206 code.writeChar(poolHelper.putClass(array)).writeByte(dims);
207 return thisBuilder();
208 }
209
210 public C vbox(S target) {
211 emitOp(Opcode.VBOX, target);
212 code.writeChar(poolHelper.putClass(target));
213 return thisBuilder();
214 }
215
216 public C vunbox(S target) {
217 emitOp(Opcode.VUNBOX, target);
218 code.writeChar(poolHelper.putClass(target));
219 return thisBuilder();
220 }
221
222 public C ldc(int i) {
223 return ldc(pool -> pool.putInt(i), false);
224 }
225
226 public C ldc(long l) {
227 return ldc(pool -> pool.putLong(l), true);
228 }
229
230 public C ldc(float f) {
231 return ldc(pool -> pool.putFloat(f), false);
232 }
233
234 public C ldc(double d) {
235 return ldc(pool -> pool.putDouble(d), true);
236 }
237
238 public C ldc(String s) {
239 return ldc(pool -> pool.putString(s), false);
240 }
241
276 public C ireturn() {
277 return emitOp(Opcode.IRETURN);
278 }
279
280 public C freturn() {
281 return emitOp(Opcode.FRETURN);
282 }
283
284 public C lreturn() {
285 return emitOp(Opcode.LRETURN);
286 }
287
288 public C dreturn() {
289 return emitOp(Opcode.DRETURN);
290 }
291
292 public C return_() {
293 return emitOp(Opcode.RETURN);
294 }
295
296 public C vreturn() {
297 return emitOp(Opcode.VRETURN);
298 }
299
300 protected C emitWideIfNeeded(Opcode opcode, int n) {
301 boolean wide = n > Byte.MAX_VALUE;
302 if (wide) {
303 wide();
304 }
305 emitOp(opcode, n);
306 if (wide) {
307 code.writeChar(n);
308 } else {
309 code.writeByte(n);
310 }
311 return thisBuilder();
312 }
313
314 protected C emitWideIfNeeded(Opcode opcode, int n, int v) {
315 boolean wide = n > Byte.MAX_VALUE || v > Byte.MAX_VALUE;
316 if (wide) {
317 wide();
318 }
319 emitOp(opcode, n);
320 if (wide) {
321 code.writeChar(n).writeChar(v);
322 } else {
323 code.writeByte(n).writeByte(v);
324 }
325 return thisBuilder();
326 }
327
328 public TypedBuilder typed(TypeTag typeTag) {
329 return typed(typeTag, _unused -> new TypedBuilder());
330 }
331
332 protected <TB extends TypedBuilder> TB typed(TypeTag typeTag, Function<TypeTag, TB> typedBuilderFunc) {
333 emitOp(Opcode.TYPED);
334 code.writeChar(poolHelper.putType(typeHelper.fromTag(typeTag)));
335 return typedBuilderFunc.apply(typeTag);
336 }
337
338 public class TypedBuilder {
339 public C aload_0() {
340 return CodeBuilder.this.aload_0();
341 }
342
343 public C aload_1() {
344 return CodeBuilder.this.aload_1();
345 }
346
347 public C aload_2() {
348 return CodeBuilder.this.aload_2();
349 }
350
351 public C aload_3() {
352 return CodeBuilder.this.aload_3();
353 }
354
355 public C aload(int n) {
356 return CodeBuilder.this.aload(n);
357 }
358
359 public C astore_0() {
360 return CodeBuilder.this.astore_0();
361 }
362
363 public C astore_1() {
364 return CodeBuilder.this.astore_1();
365 }
366
367 public C astore_2() {
368 return CodeBuilder.this.astore_2();
369 }
370
371 public C astore_3() {
372 return CodeBuilder.this.astore_3();
373 }
374
375 public C astore(int n) {
376 return CodeBuilder.this.astore(n);
377 }
378
379 public C aaload() {
380 return CodeBuilder.this.aaload();
381 }
382
383 public C aastore() {
384 return CodeBuilder.this.aastore();
385 }
386
387 public C areturn() {
388 return CodeBuilder.this.areturn();
389 }
390
391 public C anewarray(S s) {
392 return CodeBuilder.this.anewarray(s);
393 }
394
395 public C aconst_null() {
396 return CodeBuilder.this.aconst_null();
397 }
398
399 public C if_acmpeq(short target) {
400 return CodeBuilder.this.if_acmpeq(target);
401 }
402
403 public C if_acmpne(short target) {
404 return CodeBuilder.this.if_acmpeq(target);
405 }
406 }
407
408 public C vload(int i) {
409 return emitWideIfNeeded(Opcode.VLOAD, i);
410 }
411
412 public C aload(int i) {
413 return emitWideIfNeeded(Opcode.ALOAD, i);
414 }
415
416 public C iload(int i) {
417 return emitWideIfNeeded(Opcode.ILOAD, i);
418 }
419
420 public C fload(int i) {
421 return emitWideIfNeeded(Opcode.FLOAD, i);
422 }
423
424 public C lload(int i) {
425 return emitWideIfNeeded(Opcode.LLOAD, i);
426 }
427
428 public C dload(int i) {
429 return emitWideIfNeeded(Opcode.DLOAD, i);
430 }
431
492 public C aload_3() {
493 return emitOp(Opcode.ALOAD_3);
494 }
495
496 public C iload_3() {
497 return emitOp(Opcode.ILOAD_3);
498 }
499
500 public C fload_3() {
501 return emitOp(Opcode.FLOAD_3);
502 }
503
504 public C lload_3() {
505 return emitOp(Opcode.LLOAD_3);
506 }
507
508 public C dload_3() {
509 return emitOp(Opcode.DLOAD_3);
510 }
511
512 public C vstore(int i) {
513 return emitWideIfNeeded(Opcode.VSTORE, i);
514 }
515
516 public C astore(int i) {
517 return emitWideIfNeeded(Opcode.ASTORE, i);
518 }
519
520 public C istore(int i) {
521 return emitWideIfNeeded(Opcode.ISTORE, i);
522 }
523
524 public C fstore(int i) {
525 return emitWideIfNeeded(Opcode.FSTORE, i);
526 }
527
528 public C lstore(int i) {
529 return emitWideIfNeeded(Opcode.LSTORE, i);
530 }
531
532 public C dstore(int i) {
533 return emitWideIfNeeded(Opcode.DSTORE, i);
534 }
535
614 }
615
616 //...
617
618 public C iaload() {
619 return emitOp(Opcode.IALOAD);
620 }
621
622 public C laload() {
623 return emitOp(Opcode.LALOAD);
624 }
625
626 public C faload() {
627 return emitOp(Opcode.FALOAD);
628 }
629
630 public C daload() {
631 return emitOp(Opcode.DALOAD);
632 }
633
634 public C vaload() {
635 return emitOp(Opcode.VALOAD);
636 }
637
638 public C aaload() {
639 return emitOp(Opcode.AALOAD);
640 }
641
642 public C baload() {
643 return emitOp(Opcode.BALOAD);
644 }
645
646 public C caload() {
647 return emitOp(Opcode.CALOAD);
648 }
649
650 public C saload() {
651 return emitOp(Opcode.SALOAD);
652 }
653
654 public C iastore() {
655 return emitOp(Opcode.IASTORE);
656 }
657
658 public C lastore() {
659 return emitOp(Opcode.LASTORE);
660 }
661
662 public C fastore() {
663 return emitOp(Opcode.FASTORE);
664 }
665
666 public C dastore() {
667 return emitOp(Opcode.DASTORE);
668 }
669
670 public C vastore() {
671 return emitOp(Opcode.VASTORE);
672 }
673
674 public C aastore() {
675 return emitOp(Opcode.AASTORE);
676 }
677
678 public C bastore() {
679 return emitOp(Opcode.BASTORE);
680 }
681
682 public C castore() {
683 return emitOp(Opcode.CASTORE);
684 }
685
686 public C sastore() {
687 return emitOp(Opcode.SASTORE);
688 }
689
690 public C nop() {
691 return emitOp(Opcode.NOP);
692 }
693
1263 case S:
1264 case I:
1265 case Z:
1266 stackmaps.writeByte(1);
1267 break;
1268 case F:
1269 stackmaps.writeByte(2);
1270 break;
1271 case D:
1272 stackmaps.writeByte(3);
1273 break;
1274 case J:
1275 stackmaps.writeByte(4);
1276 break;
1277 case A:
1278 if (t == typeHelper.nullType()) {
1279 stackmaps.writeByte(5); //null
1280 } else {
1281 //TODO: uninit this, top?
1282 stackmaps.writeByte(7);
1283 stackmaps.writeChar(poolHelper.putClass(typeHelper.symbol(t)));
1284 }
1285 break;
1286 default:
1287 throw new IllegalStateException("Bad type");
1288 }
1289 }
1290 }
1291
1292 public void sameFrame(int offsetDelta) {
1293 int frameType = (offsetDelta < SAME_FRAME_SIZE) ?
1294 offsetDelta : SAME_FRAME_EXTENDED;
1295 stackmaps.writeByte(frameType);
1296 if (frameType == SAME_FRAME_EXTENDED) {
1297 stackmaps.writeChar(offsetDelta);
1298 }
1299 }
1300
1301 public void sameLocals1StackItemFrame(int offsetDelta, T stackItem) {
1302 int frameType = (offsetDelta < SAME_FRAME_SIZE) ?
1303 (SAME_FRAME_SIZE + offsetDelta) : SAME_LOCALS_1_STACK_ITEM_EXTENDED;
|
82 }
83
84 public C getstatic(S owner, CharSequence name, T type) {
85 emitOp(Opcode.GETSTATIC, type);
86 code.writeChar(poolHelper.putFieldRef(owner, name, type));
87 return thisBuilder();
88 }
89
90 public C putstatic(S owner, CharSequence name, T type) {
91 emitOp(Opcode.PUTSTATIC, type);
92 code.writeChar(poolHelper.putFieldRef(owner, name, type));
93 return thisBuilder();
94 }
95
96 public C getfield(S owner, CharSequence name, T type) {
97 emitOp(Opcode.GETFIELD, type);
98 code.writeChar(poolHelper.putFieldRef(owner, name, type));
99 return thisBuilder();
100 }
101
102 public C putfield(S owner, CharSequence name, T type) {
103 emitOp(Opcode.PUTFIELD, type);
104 code.writeChar(poolHelper.putFieldRef(owner, name, type));
105 return thisBuilder();
106 }
107
108 public C withfield(S owner, CharSequence name, T type) {
109 emitOp(Opcode.WITHFIELD, type);
110 code.writeChar(poolHelper.putFieldRef(owner, name, type));
111 return thisBuilder();
112 }
113
114 public C invokevirtual(S owner, CharSequence name, T type, boolean isInterface) {
115 emitOp(Opcode.INVOKEVIRTUAL, type);
116 code.writeChar(poolHelper.putMethodRef(owner, name, type, isInterface));
117 return thisBuilder();
118 }
119
120 public C invokespecial(S owner, CharSequence name, T type, boolean isInterface) {
121 emitOp(Opcode.INVOKESPECIAL, type);
122 code.writeChar(poolHelper.putMethodRef(owner, name, type, isInterface));
123 return thisBuilder();
124 }
125
126 public C invokestatic(S owner, CharSequence name, T type, boolean isInterface) {
127 emitOp(Opcode.INVOKESTATIC, type);
128 code.writeChar(poolHelper.putMethodRef(owner, name, type, isInterface));
129 return thisBuilder();
138 nargs += typeHelper.tag(it.next()).width;
139 }
140 code.writeByte(nargs);
141 code.writeByte(0);
142 return thisBuilder();
143 }
144
145 public C invokedynamic(CharSequence invokedName, T invokedType, S bsmClass, CharSequence bsmName, T bsmType, Consumer<StaticArgListBuilder<S, T, E>> staticArgs) {
146 emitOp(Opcode.INVOKEDYNAMIC, invokedType);
147 code.writeChar(poolHelper.putInvokeDynamic(invokedName, invokedType, bsmClass, bsmName, bsmType, staticArgs));
148 code.writeChar(0); //padding
149 return thisBuilder();
150 }
151
152 public C new_(S clazz) {
153 emitOp(Opcode.NEW, clazz);
154 code.writeChar(poolHelper.putClass(clazz));
155 return thisBuilder();
156 }
157
158 public C aconst_init(S clazz) {
159 emitOp(Opcode.ACONST_INIT, clazz);
160 code.writeChar(poolHelper.putClass(clazz));
161 return thisBuilder();
162 }
163
164 public C newarray(TypeTag tag) {
165 emitOp(Opcode.NEWARRAY, tag);
166 int newarraycode = tag.newarraycode;
167 if (newarraycode == -1) {
168 throw new IllegalStateException("Bad tag " + tag);
169 }
170 code.writeByte(newarraycode);
171 return thisBuilder();
172 }
173
174 public C anewarray(S array) {
175 emitOp(Opcode.ANEWARRAY, array);
176 int poolIdx = (typeHelper.isInlineClass(typeHelper.type(array))) ?
177 poolHelper.putInlineClass(array) : poolHelper.putClass(array);
178 code.writeChar(poolIdx);
179 return thisBuilder();
180 }
181
182 public C checkcast(S target) {
183 emitOp(Opcode.CHECKCAST);
184 int poolIdx = (typeHelper.isInlineClass(typeHelper.type(target))) ?
185 poolHelper.putInlineClass(target) : poolHelper.putClass(target);
186 code.writeChar(poolIdx);
187 return thisBuilder();
188 }
189
190 public C instanceof_(S target) {
191 emitOp(Opcode.INSTANCEOF);
192 int poolIdx = (typeHelper.isInlineClass(typeHelper.type(target))) ?
193 poolHelper.putInlineClass(target) : poolHelper.putClass(target);
194 code.writeChar(poolIdx);
195 return thisBuilder();
196 }
197
198 public C multianewarray(S array, byte dims) {
199 emitOp(Opcode.MULTIANEWARRAY, new Object[]{array, dims});
200 code.writeChar(poolHelper.putClass(array)).writeByte(dims);
201 return thisBuilder();
202 }
203
204 public C ldc(int i) {
205 return ldc(pool -> pool.putInt(i), false);
206 }
207
208 public C ldc(long l) {
209 return ldc(pool -> pool.putLong(l), true);
210 }
211
212 public C ldc(float f) {
213 return ldc(pool -> pool.putFloat(f), false);
214 }
215
216 public C ldc(double d) {
217 return ldc(pool -> pool.putDouble(d), true);
218 }
219
220 public C ldc(String s) {
221 return ldc(pool -> pool.putString(s), false);
222 }
223
258 public C ireturn() {
259 return emitOp(Opcode.IRETURN);
260 }
261
262 public C freturn() {
263 return emitOp(Opcode.FRETURN);
264 }
265
266 public C lreturn() {
267 return emitOp(Opcode.LRETURN);
268 }
269
270 public C dreturn() {
271 return emitOp(Opcode.DRETURN);
272 }
273
274 public C return_() {
275 return emitOp(Opcode.RETURN);
276 }
277
278 protected C emitWideIfNeeded(Opcode opcode, int n) {
279 boolean wide = n > Byte.MAX_VALUE;
280 if (wide) {
281 wide();
282 }
283 emitOp(opcode, n);
284 if (wide) {
285 code.writeChar(n);
286 } else {
287 code.writeByte(n);
288 }
289 return thisBuilder();
290 }
291
292 protected C emitWideIfNeeded(Opcode opcode, int n, int v) {
293 boolean wide = n > Byte.MAX_VALUE || v > Byte.MAX_VALUE;
294 if (wide) {
295 wide();
296 }
297 emitOp(opcode, n);
298 if (wide) {
299 code.writeChar(n).writeChar(v);
300 } else {
301 code.writeByte(n).writeByte(v);
302 }
303 return thisBuilder();
304 }
305
306 public C aload(int i) {
307 return emitWideIfNeeded(Opcode.ALOAD, i);
308 }
309
310 public C iload(int i) {
311 return emitWideIfNeeded(Opcode.ILOAD, i);
312 }
313
314 public C fload(int i) {
315 return emitWideIfNeeded(Opcode.FLOAD, i);
316 }
317
318 public C lload(int i) {
319 return emitWideIfNeeded(Opcode.LLOAD, i);
320 }
321
322 public C dload(int i) {
323 return emitWideIfNeeded(Opcode.DLOAD, i);
324 }
325
386 public C aload_3() {
387 return emitOp(Opcode.ALOAD_3);
388 }
389
390 public C iload_3() {
391 return emitOp(Opcode.ILOAD_3);
392 }
393
394 public C fload_3() {
395 return emitOp(Opcode.FLOAD_3);
396 }
397
398 public C lload_3() {
399 return emitOp(Opcode.LLOAD_3);
400 }
401
402 public C dload_3() {
403 return emitOp(Opcode.DLOAD_3);
404 }
405
406 public C astore(int i) {
407 return emitWideIfNeeded(Opcode.ASTORE, i);
408 }
409
410 public C istore(int i) {
411 return emitWideIfNeeded(Opcode.ISTORE, i);
412 }
413
414 public C fstore(int i) {
415 return emitWideIfNeeded(Opcode.FSTORE, i);
416 }
417
418 public C lstore(int i) {
419 return emitWideIfNeeded(Opcode.LSTORE, i);
420 }
421
422 public C dstore(int i) {
423 return emitWideIfNeeded(Opcode.DSTORE, i);
424 }
425
504 }
505
506 //...
507
508 public C iaload() {
509 return emitOp(Opcode.IALOAD);
510 }
511
512 public C laload() {
513 return emitOp(Opcode.LALOAD);
514 }
515
516 public C faload() {
517 return emitOp(Opcode.FALOAD);
518 }
519
520 public C daload() {
521 return emitOp(Opcode.DALOAD);
522 }
523
524 public C aaload() {
525 return emitOp(Opcode.AALOAD);
526 }
527
528 public C baload() {
529 return emitOp(Opcode.BALOAD);
530 }
531
532 public C caload() {
533 return emitOp(Opcode.CALOAD);
534 }
535
536 public C saload() {
537 return emitOp(Opcode.SALOAD);
538 }
539
540 public C iastore() {
541 return emitOp(Opcode.IASTORE);
542 }
543
544 public C lastore() {
545 return emitOp(Opcode.LASTORE);
546 }
547
548 public C fastore() {
549 return emitOp(Opcode.FASTORE);
550 }
551
552 public C dastore() {
553 return emitOp(Opcode.DASTORE);
554 }
555
556 public C aastore() {
557 return emitOp(Opcode.AASTORE);
558 }
559
560 public C bastore() {
561 return emitOp(Opcode.BASTORE);
562 }
563
564 public C castore() {
565 return emitOp(Opcode.CASTORE);
566 }
567
568 public C sastore() {
569 return emitOp(Opcode.SASTORE);
570 }
571
572 public C nop() {
573 return emitOp(Opcode.NOP);
574 }
575
1145 case S:
1146 case I:
1147 case Z:
1148 stackmaps.writeByte(1);
1149 break;
1150 case F:
1151 stackmaps.writeByte(2);
1152 break;
1153 case D:
1154 stackmaps.writeByte(3);
1155 break;
1156 case J:
1157 stackmaps.writeByte(4);
1158 break;
1159 case A:
1160 if (t == typeHelper.nullType()) {
1161 stackmaps.writeByte(5); //null
1162 } else {
1163 //TODO: uninit this, top?
1164 stackmaps.writeByte(7);
1165 stackmaps.writeChar(typeHelper.isInlineClass(t) ?
1166 poolHelper.putInlineClass(typeHelper.symbol(t)) : poolHelper.putClass(typeHelper.symbol(t)));
1167 }
1168 break;
1169 default:
1170 throw new IllegalStateException("Bad type");
1171 }
1172 }
1173 }
1174
1175 public void sameFrame(int offsetDelta) {
1176 int frameType = (offsetDelta < SAME_FRAME_SIZE) ?
1177 offsetDelta : SAME_FRAME_EXTENDED;
1178 stackmaps.writeByte(frameType);
1179 if (frameType == SAME_FRAME_EXTENDED) {
1180 stackmaps.writeChar(offsetDelta);
1181 }
1182 }
1183
1184 public void sameLocals1StackItemFrame(int offsetDelta, T stackItem) {
1185 int frameType = (offsetDelta < SAME_FRAME_SIZE) ?
1186 (SAME_FRAME_SIZE + offsetDelta) : SAME_LOCALS_1_STACK_ITEM_EXTENDED;
|