Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/jdk/internal/reflect/ClassFileAssembler.java
41159 views
1
/*
2
* Copyright (c) 2001, 2004, 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 jdk.internal.reflect;
27
28
class ClassFileAssembler implements ClassFileConstants {
29
private ByteVector vec;
30
private short cpIdx = 0;
31
32
public ClassFileAssembler() {
33
this(ByteVectorFactory.create());
34
}
35
36
public ClassFileAssembler(ByteVector vec) {
37
this.vec = vec;
38
}
39
40
public ByteVector getData() {
41
return vec;
42
}
43
44
/** Length in bytes */
45
public short getLength() {
46
return (short) vec.getLength();
47
}
48
49
public void emitMagicAndVersion() {
50
emitInt(0xCAFEBABE);
51
emitShort((short) 0);
52
emitShort((short) 49);
53
}
54
55
public void emitInt(int val) {
56
emitByte((byte) (val >> 24));
57
emitByte((byte) ((val >> 16) & 0xFF));
58
emitByte((byte) ((val >> 8) & 0xFF));
59
emitByte((byte) (val & 0xFF));
60
}
61
62
public void emitShort(short val) {
63
emitByte((byte) ((val >> 8) & 0xFF));
64
emitByte((byte) (val & 0xFF));
65
}
66
67
// Support for labels; package-private
68
void emitShort(short bci, short val) {
69
vec.put(bci, (byte) ((val >> 8) & 0xFF));
70
vec.put(bci + 1, (byte) (val & 0xFF));
71
}
72
73
public void emitByte(byte val) {
74
vec.add(val);
75
}
76
77
public void append(ClassFileAssembler asm) {
78
append(asm.vec);
79
}
80
81
public void append(ByteVector vec) {
82
for (int i = 0; i < vec.getLength(); i++) {
83
emitByte(vec.get(i));
84
}
85
}
86
87
/** Keeps track of the current (one-based) constant pool index;
88
incremented after emitting one of the following constant pool
89
entries. Can fetch the current constant pool index for use in
90
later entries. Index points at the last valid constant pool
91
entry; initially invalid. It is illegal to fetch the constant
92
pool index before emitting at least one constant pool entry. */
93
public short cpi() {
94
if (cpIdx == 0) {
95
throw new RuntimeException("Illegal use of ClassFileAssembler");
96
}
97
return cpIdx;
98
}
99
100
public void emitConstantPoolUTF8(String str) {
101
// NOTE: can not use str.getBytes("UTF-8") here because of
102
// bootstrapping issues with the character set converters.
103
byte[] bytes = UTF8.encode(str);
104
emitByte(CONSTANT_Utf8);
105
emitShort((short) bytes.length);
106
for (int i = 0; i < bytes.length; i++) {
107
emitByte(bytes[i]);
108
}
109
cpIdx++;
110
}
111
112
public void emitConstantPoolClass(short index) {
113
emitByte(CONSTANT_Class);
114
emitShort(index);
115
cpIdx++;
116
}
117
118
public void emitConstantPoolNameAndType(short nameIndex, short typeIndex) {
119
emitByte(CONSTANT_NameAndType);
120
emitShort(nameIndex);
121
emitShort(typeIndex);
122
cpIdx++;
123
}
124
125
public void emitConstantPoolFieldref
126
(short classIndex, short nameAndTypeIndex)
127
{
128
emitByte(CONSTANT_Fieldref);
129
emitShort(classIndex);
130
emitShort(nameAndTypeIndex);
131
cpIdx++;
132
}
133
134
public void emitConstantPoolMethodref
135
(short classIndex, short nameAndTypeIndex)
136
{
137
emitByte(CONSTANT_Methodref);
138
emitShort(classIndex);
139
emitShort(nameAndTypeIndex);
140
cpIdx++;
141
}
142
143
public void emitConstantPoolInterfaceMethodref
144
(short classIndex, short nameAndTypeIndex)
145
{
146
emitByte(CONSTANT_InterfaceMethodref);
147
emitShort(classIndex);
148
emitShort(nameAndTypeIndex);
149
cpIdx++;
150
}
151
152
public void emitConstantPoolString(short utf8Index) {
153
emitByte(CONSTANT_String);
154
emitShort(utf8Index);
155
cpIdx++;
156
}
157
158
//----------------------------------------------------------------------
159
// Opcodes. Keeps track of maximum stack and locals. Make a new
160
// assembler for each piece of assembled code, then append the
161
// result to the previous assembler's class file.
162
//
163
164
private int stack = 0;
165
private int maxStack = 0;
166
private int maxLocals = 0;
167
168
private void incStack() {
169
setStack(stack + 1);
170
}
171
172
private void decStack() {
173
--stack;
174
}
175
176
public short getMaxStack() {
177
return (short) maxStack;
178
}
179
180
public short getMaxLocals() {
181
return (short) maxLocals;
182
}
183
184
/** It's necessary to be able to specify the number of arguments at
185
the beginning of the method (which translates to the initial
186
value of max locals) */
187
public void setMaxLocals(int maxLocals) {
188
this.maxLocals = maxLocals;
189
}
190
191
/** Needed to do flow control. Returns current stack depth. */
192
public int getStack() {
193
return stack;
194
}
195
196
/** Needed to do flow control. */
197
public void setStack(int value) {
198
stack = value;
199
if (stack > maxStack) {
200
maxStack = stack;
201
}
202
}
203
204
///////////////
205
// Constants //
206
///////////////
207
208
public void opc_aconst_null() {
209
emitByte(opc_aconst_null);
210
incStack();
211
}
212
213
public void opc_sipush(short constant) {
214
emitByte(opc_sipush);
215
emitShort(constant);
216
incStack();
217
}
218
219
public void opc_ldc(byte cpIdx) {
220
emitByte(opc_ldc);
221
emitByte(cpIdx);
222
incStack();
223
}
224
225
/////////////////////////////////////
226
// Local variable loads and stores //
227
/////////////////////////////////////
228
229
public void opc_iload_0() {
230
emitByte(opc_iload_0);
231
if (maxLocals < 1) maxLocals = 1;
232
incStack();
233
}
234
235
public void opc_iload_1() {
236
emitByte(opc_iload_1);
237
if (maxLocals < 2) maxLocals = 2;
238
incStack();
239
}
240
241
public void opc_iload_2() {
242
emitByte(opc_iload_2);
243
if (maxLocals < 3) maxLocals = 3;
244
incStack();
245
}
246
247
public void opc_iload_3() {
248
emitByte(opc_iload_3);
249
if (maxLocals < 4) maxLocals = 4;
250
incStack();
251
}
252
253
public void opc_lload_0() {
254
emitByte(opc_lload_0);
255
if (maxLocals < 2) maxLocals = 2;
256
incStack();
257
incStack();
258
}
259
260
public void opc_lload_1() {
261
emitByte(opc_lload_1);
262
if (maxLocals < 3) maxLocals = 3;
263
incStack();
264
incStack();
265
}
266
267
public void opc_lload_2() {
268
emitByte(opc_lload_2);
269
if (maxLocals < 4) maxLocals = 4;
270
incStack();
271
incStack();
272
}
273
274
public void opc_lload_3() {
275
emitByte(opc_lload_3);
276
if (maxLocals < 5) maxLocals = 5;
277
incStack();
278
incStack();
279
}
280
281
public void opc_fload_0() {
282
emitByte(opc_fload_0);
283
if (maxLocals < 1) maxLocals = 1;
284
incStack();
285
}
286
287
public void opc_fload_1() {
288
emitByte(opc_fload_1);
289
if (maxLocals < 2) maxLocals = 2;
290
incStack();
291
}
292
293
public void opc_fload_2() {
294
emitByte(opc_fload_2);
295
if (maxLocals < 3) maxLocals = 3;
296
incStack();
297
}
298
299
public void opc_fload_3() {
300
emitByte(opc_fload_3);
301
if (maxLocals < 4) maxLocals = 4;
302
incStack();
303
}
304
305
public void opc_dload_0() {
306
emitByte(opc_dload_0);
307
if (maxLocals < 2) maxLocals = 2;
308
incStack();
309
incStack();
310
}
311
312
public void opc_dload_1() {
313
emitByte(opc_dload_1);
314
if (maxLocals < 3) maxLocals = 3;
315
incStack();
316
incStack();
317
}
318
319
public void opc_dload_2() {
320
emitByte(opc_dload_2);
321
if (maxLocals < 4) maxLocals = 4;
322
incStack();
323
incStack();
324
}
325
326
public void opc_dload_3() {
327
emitByte(opc_dload_3);
328
if (maxLocals < 5) maxLocals = 5;
329
incStack();
330
incStack();
331
}
332
333
public void opc_aload_0() {
334
emitByte(opc_aload_0);
335
if (maxLocals < 1) maxLocals = 1;
336
incStack();
337
}
338
339
public void opc_aload_1() {
340
emitByte(opc_aload_1);
341
if (maxLocals < 2) maxLocals = 2;
342
incStack();
343
}
344
345
public void opc_aload_2() {
346
emitByte(opc_aload_2);
347
if (maxLocals < 3) maxLocals = 3;
348
incStack();
349
}
350
351
public void opc_aload_3() {
352
emitByte(opc_aload_3);
353
if (maxLocals < 4) maxLocals = 4;
354
incStack();
355
}
356
357
public void opc_aaload() {
358
emitByte(opc_aaload);
359
decStack();
360
}
361
362
public void opc_astore_0() {
363
emitByte(opc_astore_0);
364
if (maxLocals < 1) maxLocals = 1;
365
decStack();
366
}
367
368
public void opc_astore_1() {
369
emitByte(opc_astore_1);
370
if (maxLocals < 2) maxLocals = 2;
371
decStack();
372
}
373
374
public void opc_astore_2() {
375
emitByte(opc_astore_2);
376
if (maxLocals < 3) maxLocals = 3;
377
decStack();
378
}
379
380
public void opc_astore_3() {
381
emitByte(opc_astore_3);
382
if (maxLocals < 4) maxLocals = 4;
383
decStack();
384
}
385
386
////////////////////////
387
// Stack manipulation //
388
////////////////////////
389
390
public void opc_pop() {
391
emitByte(opc_pop);
392
decStack();
393
}
394
395
public void opc_dup() {
396
emitByte(opc_dup);
397
incStack();
398
}
399
400
public void opc_dup_x1() {
401
emitByte(opc_dup_x1);
402
incStack();
403
}
404
405
public void opc_swap() {
406
emitByte(opc_swap);
407
}
408
409
///////////////////////////////
410
// Widening conversions only //
411
///////////////////////////////
412
413
public void opc_i2l() {
414
emitByte(opc_i2l);
415
}
416
417
public void opc_i2f() {
418
emitByte(opc_i2f);
419
}
420
421
public void opc_i2d() {
422
emitByte(opc_i2d);
423
}
424
425
public void opc_l2f() {
426
emitByte(opc_l2f);
427
}
428
429
public void opc_l2d() {
430
emitByte(opc_l2d);
431
}
432
433
public void opc_f2d() {
434
emitByte(opc_f2d);
435
}
436
437
//////////////////
438
// Control flow //
439
//////////////////
440
441
public void opc_ifeq(short bciOffset) {
442
emitByte(opc_ifeq);
443
emitShort(bciOffset);
444
decStack();
445
}
446
447
/** Control flow with forward-reference BCI. Stack assumes
448
straight-through control flow. */
449
public void opc_ifeq(Label l) {
450
short instrBCI = getLength();
451
emitByte(opc_ifeq);
452
l.add(this, instrBCI, getLength(), getStack() - 1);
453
emitShort((short) -1); // Must be patched later
454
}
455
456
public void opc_if_icmpeq(short bciOffset) {
457
emitByte(opc_if_icmpeq);
458
emitShort(bciOffset);
459
setStack(getStack() - 2);
460
}
461
462
/** Control flow with forward-reference BCI. Stack assumes straight
463
control flow. */
464
public void opc_if_icmpeq(Label l) {
465
short instrBCI = getLength();
466
emitByte(opc_if_icmpeq);
467
l.add(this, instrBCI, getLength(), getStack() - 2);
468
emitShort((short) -1); // Must be patched later
469
}
470
471
public void opc_goto(short bciOffset) {
472
emitByte(opc_goto);
473
emitShort(bciOffset);
474
}
475
476
/** Control flow with forward-reference BCI. Stack assumes straight
477
control flow. */
478
public void opc_goto(Label l) {
479
short instrBCI = getLength();
480
emitByte(opc_goto);
481
l.add(this, instrBCI, getLength(), getStack());
482
emitShort((short) -1); // Must be patched later
483
}
484
485
public void opc_ifnull(short bciOffset) {
486
emitByte(opc_ifnull);
487
emitShort(bciOffset);
488
decStack();
489
}
490
491
/** Control flow with forward-reference BCI. Stack assumes straight
492
control flow. */
493
public void opc_ifnull(Label l) {
494
short instrBCI = getLength();
495
emitByte(opc_ifnull);
496
l.add(this, instrBCI, getLength(), getStack() - 1);
497
emitShort((short) -1); // Must be patched later
498
decStack();
499
}
500
501
public void opc_ifnonnull(short bciOffset) {
502
emitByte(opc_ifnonnull);
503
emitShort(bciOffset);
504
decStack();
505
}
506
507
/** Control flow with forward-reference BCI. Stack assumes straight
508
control flow. */
509
public void opc_ifnonnull(Label l) {
510
short instrBCI = getLength();
511
emitByte(opc_ifnonnull);
512
l.add(this, instrBCI, getLength(), getStack() - 1);
513
emitShort((short) -1); // Must be patched later
514
decStack();
515
}
516
517
/////////////////////////
518
// Return instructions //
519
/////////////////////////
520
521
public void opc_ireturn() {
522
emitByte(opc_ireturn);
523
setStack(0);
524
}
525
526
public void opc_lreturn() {
527
emitByte(opc_lreturn);
528
setStack(0);
529
}
530
531
public void opc_freturn() {
532
emitByte(opc_freturn);
533
setStack(0);
534
}
535
536
public void opc_dreturn() {
537
emitByte(opc_dreturn);
538
setStack(0);
539
}
540
541
public void opc_areturn() {
542
emitByte(opc_areturn);
543
setStack(0);
544
}
545
546
public void opc_return() {
547
emitByte(opc_return);
548
setStack(0);
549
}
550
551
//////////////////////
552
// Field operations //
553
//////////////////////
554
555
public void opc_getstatic(short fieldIndex, int fieldSizeInStackSlots) {
556
emitByte(opc_getstatic);
557
emitShort(fieldIndex);
558
setStack(getStack() + fieldSizeInStackSlots);
559
}
560
561
public void opc_putstatic(short fieldIndex, int fieldSizeInStackSlots) {
562
emitByte(opc_putstatic);
563
emitShort(fieldIndex);
564
setStack(getStack() - fieldSizeInStackSlots);
565
}
566
567
public void opc_getfield(short fieldIndex, int fieldSizeInStackSlots) {
568
emitByte(opc_getfield);
569
emitShort(fieldIndex);
570
setStack(getStack() + fieldSizeInStackSlots - 1);
571
}
572
573
public void opc_putfield(short fieldIndex, int fieldSizeInStackSlots) {
574
emitByte(opc_putfield);
575
emitShort(fieldIndex);
576
setStack(getStack() - fieldSizeInStackSlots - 1);
577
}
578
579
////////////////////////
580
// Method invocations //
581
////////////////////////
582
583
/** Long and double arguments and return types count as 2 arguments;
584
other values count as 1. */
585
public void opc_invokevirtual(short methodIndex,
586
int numArgs,
587
int numReturnValues)
588
{
589
emitByte(opc_invokevirtual);
590
emitShort(methodIndex);
591
setStack(getStack() - numArgs - 1 + numReturnValues);
592
}
593
594
/** Long and double arguments and return types count as 2 arguments;
595
other values count as 1. */
596
public void opc_invokespecial(short methodIndex,
597
int numArgs,
598
int numReturnValues)
599
{
600
emitByte(opc_invokespecial);
601
emitShort(methodIndex);
602
setStack(getStack() - numArgs - 1 + numReturnValues);
603
}
604
605
/** Long and double arguments and return types count as 2 arguments;
606
other values count as 1. */
607
public void opc_invokestatic(short methodIndex,
608
int numArgs,
609
int numReturnValues)
610
{
611
emitByte(opc_invokestatic);
612
emitShort(methodIndex);
613
setStack(getStack() - numArgs + numReturnValues);
614
}
615
616
/** Long and double arguments and return types count as 2 arguments;
617
other values count as 1. */
618
public void opc_invokeinterface(short methodIndex,
619
int numArgs,
620
byte count,
621
int numReturnValues)
622
{
623
emitByte(opc_invokeinterface);
624
emitShort(methodIndex);
625
emitByte(count);
626
emitByte((byte) 0);
627
setStack(getStack() - numArgs - 1 + numReturnValues);
628
}
629
630
//////////////////
631
// Array length //
632
//////////////////
633
634
public void opc_arraylength() {
635
emitByte(opc_arraylength);
636
}
637
638
/////////
639
// New //
640
/////////
641
642
public void opc_new(short classIndex) {
643
emitByte(opc_new);
644
emitShort(classIndex);
645
incStack();
646
}
647
648
////////////
649
// Athrow //
650
////////////
651
652
public void opc_athrow() {
653
emitByte(opc_athrow);
654
setStack(1);
655
}
656
657
//////////////////////////////
658
// Checkcast and instanceof //
659
//////////////////////////////
660
661
/** Assumes the checkcast succeeds */
662
public void opc_checkcast(short classIndex) {
663
emitByte(opc_checkcast);
664
emitShort(classIndex);
665
}
666
667
public void opc_instanceof(short classIndex) {
668
emitByte(opc_instanceof);
669
emitShort(classIndex);
670
}
671
}
672
673