Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/tools/asm/Instruction.java
38918 views
1
/*
2
* Copyright (c) 1994, 2013, 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 sun.tools.asm;
27
28
import sun.tools.java.*;
29
import java.util.Enumeration;
30
import java.io.IOException;
31
import java.io.DataOutputStream;
32
33
/**
34
* An Java instruction
35
*
36
* WARNING: The contents of this source file are not part of any
37
* supported API. Code that depends on them does so at its own risk:
38
* they are subject to change or removal without notice.
39
*/
40
public
41
class Instruction implements Constants {
42
long where;
43
int pc;
44
int opc;
45
Object value;
46
Instruction next;
47
//JCOV
48
boolean flagCondInverted; /* if true, the condition is reversed
49
relatively of source code */
50
boolean flagNoCovered = false; /* if true, the command will
51
ignored for coverage */
52
53
54
/**
55
* Constructor
56
*/
57
public Instruction(long where, int opc, Object value, boolean flagCondInverted) {
58
this.where = where;
59
this.opc = opc;
60
this.value = value;
61
this.flagCondInverted = flagCondInverted;
62
}
63
64
/**
65
* Constructor
66
*/
67
public Instruction(boolean flagNoCovered, long where, int opc, Object value) {
68
this.where = where;
69
this.opc = opc;
70
this.value = value;
71
this.flagNoCovered = flagNoCovered;
72
}
73
74
/**
75
* Constructor
76
*/
77
public Instruction(long where, int opc, boolean flagNoCovered) {
78
this.where = where;
79
this.opc = opc;
80
this.flagNoCovered = flagNoCovered;
81
}
82
//end JCOV
83
84
/**
85
* Constructor
86
*/
87
public Instruction(long where, int opc, Object value) {
88
this.where = where;
89
this.opc = opc;
90
this.value = value;
91
}
92
93
/**
94
* When deciding between a lookupswitch and a tableswitch, this
95
* value is used in determining how much size increase is
96
* acceptable.
97
*/
98
public static final double SWITCHRATIO;
99
100
static {
101
// Set SWITCHRATIO from the property javac.switchratio
102
// if it exists and is reasonable. Otherwise, set
103
// SWITCHRATIO to 1.5, meaning that we will accept a 1.5x
104
// blowup (for the instruction) to use a tableswitch instead
105
// of a lookupswitch.
106
double ratio = 1.5;
107
String valStr = System.getProperty("javac.switchratio");
108
if (valStr != null) {
109
try {
110
double temp = Double.valueOf(valStr).doubleValue();
111
if (!(Double.isNaN(temp) || temp < 0.0)) {
112
ratio = temp;
113
}
114
} catch (NumberFormatException ee) {}
115
}
116
SWITCHRATIO = ratio;
117
}
118
119
/**
120
* Accessor
121
*/
122
public int getOpcode() {
123
return pc;
124
}
125
126
public Object getValue() {
127
return value;
128
}
129
130
public void setValue(Object value) {
131
this.value = value;
132
}
133
134
135
/**
136
* Optimize
137
*/
138
void optimize(Environment env) {
139
switch (opc) {
140
case opc_istore: case opc_lstore: case opc_fstore:
141
case opc_dstore: case opc_astore:
142
// Don't keep the LocalVariable info around, unless we
143
// are actually going to generate a local variable table.
144
if ((value instanceof LocalVariable) && !env.debug_vars()) {
145
value = new Integer(((LocalVariable)value).slot);
146
}
147
break;
148
149
case opc_goto: {
150
Label lbl = (Label)value;
151
value = lbl = lbl.getDestination();
152
if (lbl == next) {
153
// goto to the next instruction, obsolete
154
opc = opc_dead;
155
break;
156
}
157
158
// We optimize
159
//
160
// goto Tag
161
// ...
162
// Tag:
163
// return
164
//
165
// except when we're generating debuggable code. When
166
// we're generating debuggable code, we leave it alone,
167
// in order to provide better stepping behavior. Consider
168
// a method the end of which looks like this:
169
//
170
// ...
171
// break;
172
// } // end of loop
173
// } // end of method
174
//
175
// If we optimize the goto away, we'll be left with a
176
// single instruction (return) and the need to ascribe that
177
// instruction to two source lines (the break statement and
178
// the method's right curly). Can't get there from here.
179
// Depending on which line-number ascription we choose, the
180
// stepping user will step directly from the break statement
181
// back into the caller of the method (case 1) or from the
182
// statement that precedes the break statement to the method's
183
// right curly (case 2). Similarly, he'll be able to set a
184
// breakpoint on the break statement (case 1) or the method's
185
// right curly (case 2), but not on both. Neither case 1 nor
186
// case 2 is desirable. .We want him to see both the break
187
// statement and the method's right curly when stepping,
188
// and we want him to be able to set a breakpoint on either or
189
// both. So we suppress the optimization when generating
190
// debuggable code.
191
// (Above notes from brucek@eng in JDK1.0.2, copied here
192
// by kelly.ohair@eng for JDK1.1)
193
//
194
// With the changes to allow -O and -g at the same time,
195
// I've changed the condition to be whether optimization is
196
// on instead of the debugging flag being off.
197
// - david.stoutamire@eng for 1.2
198
199
if (lbl.next != null && env.opt()) {
200
switch (lbl.next.opc) {
201
case opc_return: case opc_ireturn: case opc_lreturn:
202
case opc_freturn: case opc_dreturn: case opc_areturn:
203
// goto to return
204
opc = lbl.next.opc;
205
value = lbl.next.value;
206
break;
207
}
208
}
209
break;
210
}
211
212
case opc_ifeq: case opc_ifne: case opc_ifgt:
213
case opc_ifge: case opc_iflt: case opc_ifle:
214
case opc_ifnull: case opc_ifnonnull:
215
value = ((Label)value).getDestination();
216
if (value == next) {
217
// branch to next instruction, obsolete
218
opc = opc_pop;
219
break;
220
}
221
if ((next.opc == opc_goto) && (value == next.next)) {
222
// Conditional branch over goto, invert
223
// Note that you can't invert all conditions, condition
224
// results for float/double compares are not invertable.
225
switch (opc) {
226
case opc_ifeq: opc = opc_ifne; break;
227
case opc_ifne: opc = opc_ifeq; break;
228
case opc_iflt: opc = opc_ifge; break;
229
case opc_ifle: opc = opc_ifgt; break;
230
case opc_ifgt: opc = opc_ifle; break;
231
case opc_ifge: opc = opc_iflt; break;
232
case opc_ifnull: opc = opc_ifnonnull; break;
233
case opc_ifnonnull: opc = opc_ifnull; break;
234
}
235
//JCOV
236
flagCondInverted = !flagCondInverted;
237
//end JCOV
238
value = next.value;
239
next.opc = opc_dead;
240
}
241
break;
242
243
case opc_if_acmpeq: case opc_if_acmpne:
244
case opc_if_icmpeq: case opc_if_icmpne:
245
case opc_if_icmpgt: case opc_if_icmpge:
246
case opc_if_icmplt: case opc_if_icmple:
247
value = ((Label)value).getDestination();
248
if (value == next) {
249
// branch to next instruction, obsolete
250
opc = opc_pop2;
251
break;
252
}
253
if ((next.opc == opc_goto) && (value == next.next)) {
254
// Conditional branch over goto, invert
255
switch (opc) {
256
case opc_if_acmpeq: opc = opc_if_acmpne; break;
257
case opc_if_acmpne: opc = opc_if_acmpeq; break;
258
case opc_if_icmpeq: opc = opc_if_icmpne; break;
259
case opc_if_icmpne: opc = opc_if_icmpeq; break;
260
case opc_if_icmpgt: opc = opc_if_icmple; break;
261
case opc_if_icmpge: opc = opc_if_icmplt; break;
262
case opc_if_icmplt: opc = opc_if_icmpge; break;
263
case opc_if_icmple: opc = opc_if_icmpgt; break;
264
}
265
//JCOV
266
flagCondInverted = !flagCondInverted;
267
//end JCOV
268
value = next.value;
269
next.opc = opc_dead;
270
}
271
break;
272
273
case opc_tableswitch:
274
case opc_lookupswitch: {
275
SwitchData sw = (SwitchData)value;
276
sw.defaultLabel = sw.defaultLabel.getDestination();
277
for (Enumeration<Integer> e = sw.tab.keys() ; e.hasMoreElements() ; ) {
278
Integer k = e.nextElement();
279
Label lbl = sw.tab.get(k);
280
sw.tab.put(k, lbl.getDestination());
281
}
282
283
// Compute the approximate sizes of a tableswitch and a
284
// lookupswitch. Decide which one we want to generate.
285
286
long range = (long)sw.maxValue - (long)sw.minValue + 1;
287
long entries = sw.tab.size();
288
289
long tableSize = 4 + range;
290
long lookupSize = 3 + 2 * entries;
291
292
if (tableSize <= lookupSize * SWITCHRATIO) {
293
opc = opc_tableswitch;
294
} else {
295
opc = opc_lookupswitch;
296
}
297
break;
298
}
299
300
}
301
}
302
303
/**
304
* Collect constants into the constant table
305
*/
306
void collect(ConstantPool tab) {
307
switch (opc) {
308
case opc_istore: case opc_lstore: case opc_fstore:
309
case opc_dstore: case opc_astore:
310
if (value instanceof LocalVariable) {
311
MemberDefinition field = ((LocalVariable)value).field;
312
tab.put(field.getName().toString());
313
tab.put(field.getType().getTypeSignature());
314
}
315
return;
316
317
case opc_new: case opc_putfield:
318
case opc_putstatic: case opc_getfield:
319
case opc_getstatic: case opc_invokevirtual:
320
case opc_invokespecial: case opc_invokestatic:
321
case opc_invokeinterface: case opc_instanceof:
322
case opc_checkcast:
323
tab.put(value);
324
return;
325
326
case opc_anewarray:
327
tab.put(value);
328
return;
329
330
case opc_multianewarray:
331
tab.put(((ArrayData)value).type);
332
return;
333
334
case opc_ldc:
335
case opc_ldc_w:
336
if (value instanceof Integer) {
337
int v = ((Integer)value).intValue();
338
if ((v >= -1) && (v <= 5)) {
339
opc = opc_iconst_0 + v;
340
return;
341
} else if ((v >= -(1 << 7)) && (v < (1 << 7))) {
342
opc = opc_bipush;
343
return;
344
} else if ((v >= -(1 << 15)) && (v < (1 << 15))) {
345
opc = opc_sipush;
346
return;
347
}
348
} else if (value instanceof Float) {
349
float v = ((Float)value).floatValue();
350
if (v == 0) {
351
if (Float.floatToIntBits(v) == 0) {
352
opc = opc_fconst_0;
353
return;
354
}
355
} else if (v == 1) {
356
opc = opc_fconst_1;
357
return;
358
} else if (v == 2) {
359
opc = opc_fconst_2;
360
return;
361
}
362
}
363
tab.put(value);
364
return;
365
366
case opc_ldc2_w:
367
if (value instanceof Long) {
368
long v = ((Long)value).longValue();
369
if (v == 0) {
370
opc = opc_lconst_0;
371
return;
372
} else if (v == 1) {
373
opc = opc_lconst_1;
374
return;
375
}
376
} else if (value instanceof Double) {
377
double v = ((Double)value).doubleValue();
378
if (v == 0) {
379
if (Double.doubleToLongBits(v) == 0) {
380
opc = opc_dconst_0;
381
return;
382
}
383
} else if (v == 1) {
384
opc = opc_dconst_1;
385
return;
386
}
387
}
388
tab.put(value);
389
return;
390
391
case opc_try:
392
for (Enumeration<CatchData> e = ((TryData)value).catches.elements() ; e.hasMoreElements() ;) {
393
CatchData cd = e.nextElement();
394
if (cd.getType() != null) {
395
tab.put(cd.getType());
396
}
397
}
398
return;
399
400
case opc_nop:
401
if ((value != null) && (value instanceof ClassDeclaration))
402
tab.put(value);
403
return;
404
}
405
}
406
407
/**
408
* Balance the stack
409
*/
410
int balance() {
411
switch (opc) {
412
case opc_dead: case opc_label: case opc_iinc:
413
case opc_arraylength: case opc_laload: case opc_daload:
414
case opc_nop: case opc_ineg: case opc_fneg:
415
case opc_lneg: case opc_dneg: case opc_i2f:
416
case opc_f2i: case opc_l2d: case opc_d2l:
417
case opc_i2b: case opc_i2c: case opc_i2s:
418
case opc_jsr: case opc_goto: case opc_jsr_w:
419
case opc_goto_w: case opc_return: case opc_ret:
420
case opc_instanceof: case opc_checkcast: case opc_newarray:
421
case opc_anewarray: case opc_try: case opc_swap:
422
return 0;
423
424
case opc_ldc: case opc_ldc_w: case opc_bipush:
425
case opc_sipush: case opc_aconst_null: case opc_iconst_m1:
426
case opc_iconst_0: case opc_iconst_1: case opc_iconst_2:
427
case opc_iconst_3: case opc_iconst_4: case opc_iconst_5:
428
case opc_fconst_0: case opc_fconst_1: case opc_fconst_2:
429
case opc_iload: case opc_fload: case opc_aload:
430
case opc_dup: case opc_dup_x1: case opc_dup_x2:
431
case opc_i2l: case opc_i2d: case opc_f2l:
432
case opc_f2d: case opc_new:
433
return 1;
434
435
case opc_lload: case opc_dload: case opc_dup2:
436
case opc_dup2_x1: case opc_dup2_x2: case opc_ldc2_w:
437
case opc_lconst_0: case opc_lconst_1: case opc_dconst_0:
438
case opc_dconst_1:
439
return 2;
440
441
case opc_istore: case opc_fstore: case opc_astore:
442
case opc_iaload: case opc_faload: case opc_aaload:
443
case opc_baload: case opc_caload: case opc_saload:
444
case opc_pop: case opc_iadd: case opc_fadd:
445
case opc_isub: case opc_fsub: case opc_imul:
446
case opc_fmul: case opc_idiv: case opc_fdiv:
447
case opc_irem: case opc_frem: case opc_ishl:
448
case opc_ishr: case opc_iushr: case opc_lshl:
449
case opc_lshr: case opc_lushr: case opc_iand:
450
case opc_ior: case opc_ixor: case opc_l2i:
451
case opc_l2f: case opc_d2i: case opc_d2f:
452
case opc_ifeq: case opc_ifne: case opc_iflt:
453
case opc_ifle: case opc_ifgt: case opc_ifge:
454
case opc_ifnull: case opc_ifnonnull: case opc_fcmpl:
455
case opc_fcmpg: case opc_ireturn: case opc_freturn:
456
case opc_areturn: case opc_tableswitch: case opc_lookupswitch:
457
case opc_athrow: case opc_monitorenter: case opc_monitorexit:
458
return -1;
459
460
case opc_lstore: case opc_dstore: case opc_pop2:
461
case opc_ladd: case opc_dadd: case opc_lsub:
462
case opc_dsub: case opc_lmul: case opc_dmul:
463
case opc_ldiv: case opc_ddiv: case opc_lrem:
464
case opc_drem: case opc_land: case opc_lor:
465
case opc_lxor: case opc_if_acmpeq: case opc_if_acmpne:
466
case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmplt:
467
case opc_if_icmple: case opc_if_icmpgt: case opc_if_icmpge:
468
case opc_lreturn: case opc_dreturn:
469
return -2;
470
471
case opc_iastore: case opc_fastore: case opc_aastore:
472
case opc_bastore: case opc_castore: case opc_sastore:
473
case opc_lcmp: case opc_dcmpl: case opc_dcmpg:
474
return -3;
475
476
case opc_lastore: case opc_dastore:
477
return -4;
478
479
case opc_multianewarray:
480
return 1 - ((ArrayData)value).nargs;
481
482
case opc_getfield:
483
return ((MemberDefinition)value).getType().stackSize() - 1;
484
485
case opc_putfield:
486
return -1 - ((MemberDefinition)value).getType().stackSize();
487
488
case opc_getstatic:
489
return ((MemberDefinition)value).getType().stackSize();
490
491
case opc_putstatic:
492
return -((MemberDefinition)value).getType().stackSize();
493
494
case opc_invokevirtual:
495
case opc_invokespecial:
496
case opc_invokeinterface:
497
return ((MemberDefinition)value).getType().getReturnType().stackSize() -
498
(((MemberDefinition)value).getType().stackSize() + 1);
499
500
case opc_invokestatic:
501
return ((MemberDefinition)value).getType().getReturnType().stackSize() -
502
(((MemberDefinition)value).getType().stackSize());
503
}
504
throw new CompilerError("invalid opcode: " + toString());
505
}
506
507
/**
508
* Return the size of the instruction
509
*/
510
int size(ConstantPool tab) {
511
switch (opc) {
512
case opc_try: case opc_label: case opc_dead:
513
return 0;
514
515
case opc_bipush: case opc_newarray:
516
return 2;
517
518
case opc_sipush: case opc_goto: case opc_jsr:
519
case opc_ifeq: case opc_ifne: case opc_ifgt:
520
case opc_ifge: case opc_iflt: case opc_ifle:
521
case opc_ifnull: case opc_ifnonnull: case opc_if_acmpeq:
522
case opc_if_acmpne: case opc_if_icmpeq: case opc_if_icmpne:
523
case opc_if_icmpgt: case opc_if_icmpge: case opc_if_icmplt:
524
case opc_if_icmple:
525
return 3;
526
527
case opc_ldc:
528
case opc_ldc_w:
529
if (tab.index(value) < 256) {
530
opc = opc_ldc;
531
return 2;
532
} else {
533
opc = opc_ldc_w;
534
return 3;
535
}
536
537
case opc_iload: case opc_lload: case opc_fload:
538
case opc_dload: case opc_aload: {
539
int v = ((Number)value).intValue();
540
if (v < 4) {
541
if (v < 0) {
542
throw new CompilerError("invalid slot: " + toString()
543
+ "\nThis error possibly resulted from poorly constructed class paths.");
544
}
545
opc = opc_iload_0 + (opc - opc_iload) * 4 + v;
546
return 1;
547
} else if (v <= 255) {
548
return 2;
549
} else {
550
opc += 256; // indicate wide variant
551
return 4;
552
}
553
}
554
555
case opc_iinc: {
556
int register = ((int[])value)[0];
557
int increment = ((int[])value)[1];
558
if (register < 0) {
559
throw new CompilerError("invalid slot: " + toString());
560
}
561
if (register <= 255 && (((byte)increment) == increment)) {
562
return 3;
563
} else {
564
opc += 256; // indicate wide variant
565
return 6;
566
}
567
}
568
569
case opc_istore: case opc_lstore: case opc_fstore:
570
case opc_dstore: case opc_astore: {
571
int v = (value instanceof Number) ?
572
((Number)value).intValue() : ((LocalVariable)value).slot;
573
if (v < 4) {
574
if (v < 0) {
575
throw new CompilerError("invalid slot: " + toString());
576
}
577
opc = opc_istore_0 + (opc - opc_istore) * 4 + v;
578
return 1;
579
} else if (v <= 255) {
580
return 2;
581
} else {
582
opc += 256; // indicate wide variant
583
return 4;
584
}
585
}
586
587
case opc_ret: {
588
int v = ((Number)value).intValue();
589
if (v <= 255) {
590
if (v < 0) {
591
throw new CompilerError("invalid slot: " + toString());
592
}
593
return 2;
594
} else {
595
opc += 256; // indicate wide variant
596
return 4;
597
}
598
}
599
600
case opc_ldc2_w: case opc_new:
601
case opc_putstatic: case opc_getstatic:
602
case opc_putfield: case opc_getfield:
603
case opc_invokevirtual: case opc_invokespecial:
604
case opc_invokestatic: case opc_instanceof:
605
case opc_checkcast: case opc_anewarray:
606
return 3;
607
608
case opc_multianewarray:
609
return 4;
610
611
case opc_invokeinterface:
612
case opc_goto_w:
613
case opc_jsr_w:
614
return 5;
615
616
case opc_tableswitch: {
617
SwitchData sw = (SwitchData)value;
618
int n = 1;
619
for(; ((pc + n) % 4) != 0 ; n++);
620
return n + 16 + (sw.maxValue - sw.minValue) * 4;
621
}
622
623
case opc_lookupswitch: {
624
SwitchData sw = (SwitchData)value;
625
int n = 1;
626
for(; ((pc + n) % 4) != 0 ; n++);
627
return n + 8 + sw.tab.size() * 8;
628
}
629
630
case opc_nop:
631
if ((value != null) && !(value instanceof Integer))
632
return 2;
633
else
634
return 1;
635
}
636
637
// most opcodes are only 1 byte long
638
return 1;
639
}
640
641
/**
642
* Generate code
643
*/
644
@SuppressWarnings("fallthrough")
645
void write(DataOutputStream out, ConstantPool tab) throws IOException {
646
switch (opc) {
647
case opc_try: case opc_label: case opc_dead:
648
break;
649
650
case opc_bipush: case opc_newarray:
651
case opc_iload: case opc_lload: case opc_fload:
652
case opc_dload: case opc_aload: case opc_ret:
653
out.writeByte(opc);
654
out.writeByte(((Number)value).intValue());
655
break;
656
657
case opc_iload + 256: case opc_lload + 256:
658
case opc_fload + 256: case opc_dload + 256:
659
case opc_aload + 256: case opc_ret + 256:
660
out.writeByte(opc_wide);
661
out.writeByte(opc - 256);
662
out.writeShort(((Number)value).intValue());
663
break;
664
665
case opc_istore: case opc_lstore: case opc_fstore:
666
case opc_dstore: case opc_astore:
667
out.writeByte(opc);
668
out.writeByte((value instanceof Number) ?
669
((Number)value).intValue() : ((LocalVariable)value).slot);
670
break;
671
672
case opc_istore + 256: case opc_lstore + 256:
673
case opc_fstore + 256: case opc_dstore + 256:
674
case opc_astore + 256:
675
out.writeByte(opc_wide);
676
out.writeByte(opc - 256);
677
out.writeShort((value instanceof Number) ?
678
((Number)value).intValue() : ((LocalVariable)value).slot);
679
break;
680
681
case opc_sipush:
682
out.writeByte(opc);
683
out.writeShort(((Number)value).intValue());
684
break;
685
686
case opc_ldc:
687
out.writeByte(opc);
688
out.writeByte(tab.index(value));
689
break;
690
691
case opc_ldc_w: case opc_ldc2_w:
692
case opc_new: case opc_putstatic:
693
case opc_getstatic: case opc_putfield:
694
case opc_getfield: case opc_invokevirtual:
695
case opc_invokespecial: case opc_invokestatic:
696
case opc_instanceof: case opc_checkcast:
697
out.writeByte(opc);
698
out.writeShort(tab.index(value));
699
break;
700
701
case opc_iinc:
702
out.writeByte(opc);
703
out.writeByte(((int[])value)[0]); // register
704
out.writeByte(((int[])value)[1]); // increment
705
break;
706
707
case opc_iinc + 256:
708
out.writeByte(opc_wide);
709
out.writeByte(opc - 256);
710
out.writeShort(((int[])value)[0]); // register
711
out.writeShort(((int[])value)[1]); // increment
712
break;
713
714
case opc_anewarray:
715
out.writeByte(opc);
716
out.writeShort(tab.index(value));
717
break;
718
719
case opc_multianewarray:
720
out.writeByte(opc);
721
out.writeShort(tab.index(((ArrayData)value).type));
722
out.writeByte(((ArrayData)value).nargs);
723
break;
724
725
case opc_invokeinterface:
726
out.writeByte(opc);
727
out.writeShort(tab.index(value));
728
out.writeByte(((MemberDefinition)value).getType().stackSize() + 1);
729
out.writeByte(0);
730
break;
731
732
case opc_goto: case opc_jsr: case opc_ifeq:
733
case opc_ifne: case opc_ifgt: case opc_ifge:
734
case opc_iflt: case opc_ifle: case opc_ifnull:
735
case opc_ifnonnull: case opc_if_acmpeq: case opc_if_acmpne:
736
case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpgt:
737
case opc_if_icmpge: case opc_if_icmplt: case opc_if_icmple:
738
out.writeByte(opc);
739
out.writeShort(((Instruction)value).pc - pc);
740
break;
741
742
case opc_goto_w:
743
case opc_jsr_w:
744
out.writeByte(opc);
745
out.writeLong(((Instruction)value).pc - pc);
746
break;
747
748
case opc_tableswitch: {
749
SwitchData sw = (SwitchData)value;
750
out.writeByte(opc);
751
for(int n = 1 ; ((pc + n) % 4) != 0 ; n++) {
752
out.writeByte(0);
753
}
754
out.writeInt(sw.defaultLabel.pc - pc);
755
out.writeInt(sw.minValue);
756
out.writeInt(sw.maxValue);
757
for (int n = sw.minValue ; n <= sw.maxValue ; n++) {
758
Label lbl = sw.get(n);
759
int target_pc = (lbl != null) ? lbl.pc : sw.defaultLabel.pc;
760
out.writeInt(target_pc - pc);
761
}
762
break;
763
}
764
765
case opc_lookupswitch: {
766
SwitchData sw = (SwitchData)value;
767
out.writeByte(opc);
768
int n = pc + 1;
769
for(; (n % 4) != 0 ; n++) {
770
out.writeByte(0);
771
}
772
out.writeInt(sw.defaultLabel.pc - pc);
773
out.writeInt(sw.tab.size());
774
for (Enumeration<Integer> e = sw.sortedKeys(); e.hasMoreElements() ; ) {
775
Integer v = e.nextElement();
776
out.writeInt(v.intValue());
777
out.writeInt(sw.get(v).pc - pc);
778
}
779
break;
780
}
781
782
case opc_nop:
783
if (value != null) {
784
if (value instanceof Integer)
785
out.writeByte(((Integer)value).intValue());
786
else
787
out.writeShort(tab.index(value));
788
return;
789
}
790
// fall through
791
792
default:
793
out.writeByte(opc);
794
break;
795
}
796
}
797
798
/**
799
* toString
800
*/
801
public String toString() {
802
String prefix = (where >> WHEREOFFSETBITS) + ":\t";
803
switch (opc) {
804
case opc_try:
805
return prefix + "try " + ((TryData)value).getEndLabel().hashCode();
806
807
case opc_dead:
808
return prefix + "dead";
809
810
case opc_iinc: {
811
int register = ((int[])value)[0];
812
int increment = ((int[])value)[1];
813
return prefix + opcNames[opc] + " " + register + ", " + increment;
814
}
815
816
default:
817
if (value != null) {
818
if (value instanceof Label) {
819
return prefix + opcNames[opc] + " " + value.toString();
820
} else if (value instanceof Instruction) {
821
return prefix + opcNames[opc] + " " + value.hashCode();
822
} else if (value instanceof String) {
823
return prefix + opcNames[opc] + " \"" + value + "\"";
824
} else {
825
return prefix + opcNames[opc] + " " + value;
826
}
827
} else {
828
return prefix + opcNames[opc];
829
}
830
}
831
}
832
}
833
834