KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > base > bcg > CodeBuilder


1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the compiler and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  *
22  * Contributor(s):
23  */

24
25 package org.aspectj.compiler.base.bcg;
26
27 import org.aspectj.compiler.base.bcg.pool.*;
28
29 import java.io.OutputStream JavaDoc;
30 import java.io.DataOutputStream JavaDoc;
31 import java.io.PrintStream JavaDoc;
32 import java.io.IOException JavaDoc;
33
34 import java.util.HashSet JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.util.Arrays JavaDoc;
37 import java.util.List JavaDoc;
38 import java.util.Map JavaDoc;
39 import java.util.HashMap JavaDoc;
40 import java.util.Stack JavaDoc;
41 import java.util.ArrayList JavaDoc;
42 import java.util.Iterator JavaDoc;
43 import java.util.ListIterator JavaDoc;
44
45 // XXX annoying big modularity violation.
46
import org.aspectj.compiler.base.JavaCompiler;
47 import org.aspectj.compiler.base.ast.ControlContext;
48 import org.aspectj.compiler.base.ast.VarDec;
49 import org.aspectj.compiler.base.ast.LabeledStmt;
50 import org.aspectj.compiler.base.ast.WindingStmt;
51 import org.aspectj.compiler.base.ast.Stmt;
52 import org.aspectj.compiler.base.ast.Type;
53 import org.aspectj.compiler.base.ast.ArrayType;
54 import org.aspectj.compiler.base.ast.RefType;
55 import org.aspectj.compiler.base.ast.NameType;
56 import org.aspectj.compiler.base.ast.SourceLocation;
57
58 /** Lifecycle: creation, addition of code (through the emitX methods),
59     resolution of constant pool (done in the constant pool, when all
60     constant pool entries are set), resolution of this, output. It is
61     an error for these steps to occur out of order. It is checked
62     that this is resolved after the constant pool, and printed after
63     it is resolved. It is still possible to mess up by resolving the
64     constant pool and adding new codes to this, but that shouldn't
65     matter, since the constant pool can't be resolved twice. */

66 public final class CodeBuilder {
67
68     // ------------------------------
69
// state
70

71     private boolean isResolvedFlag = false;
72     public boolean isResolved() { return isResolvedFlag; }
73
74     // ------------------------------
75
// state
76

77     ConstantPool pool;
78     ClassfileBuilder cfb;
79     Attributes attributes;
80     CodeBuilder(ClassfileBuilder cfb) {
81         this.cfb = cfb;
82         this.pool = cfb.pool;
83         this.attributes = new Attributes(pool);
84     }
85
86     public JavaCompiler getCompiler() { return cfb.getCompiler(); }
87
88     int maxFrame;
89     public void setMaxFrame(int maxFrame) {
90         this.maxFrame = maxFrame;
91     }
92     int maxStack = 0;
93     int stackSize = 0;
94
95     /* Label */ List JavaDoc starts = new ArrayList JavaDoc();
96     /* Label */ List JavaDoc ends = new ArrayList JavaDoc();
97     /* Label */ List JavaDoc handlers = new ArrayList JavaDoc();
98     /* Constant */ List JavaDoc names = new ArrayList JavaDoc();
99
100     List JavaDoc codes = new ArrayList JavaDoc();
101     Code[] codea;
102
103     List JavaDoc labels = new ArrayList JavaDoc();
104
105     // ------------------------------
106
// stack
107

108     public int getStackSize() {
109         return stackSize;
110     }
111     public void pushStack(int delta) {
112         stackSize += delta;
113         stackInvariant();
114     }
115     public void adjustStack(int delta) {
116         pushStack(delta);
117     }
118     public void popStack(int delta) {
119         stackSize -= delta;
120     }
121     public void setStackSize(int ss) {
122         stackSize = ss;
123         stackInvariant();
124     }
125     public void clearStack() {
126         stackSize = 0;
127     }
128     private void stackInvariant() {
129         if (stackSize > maxStack) maxStack = stackSize;
130     }
131
132     // ------------------------------
133
// control context
134

135     private ControlContext context = new ControlContext();
136     private Map JavaDoc breakLabels = new HashMap JavaDoc();
137     private Map JavaDoc continueLabels = new HashMap JavaDoc();
138     private Map JavaDoc windingLabels = new HashMap JavaDoc();
139
140     public void enterNonWindingContext(Stmt s, Label b, Label c) {
141         context.enter(s);
142         breakLabels.put(s, b);
143         if (c != null) continueLabels.put(s, c);
144     }
145     public void enterWindingContext(Stmt s, Label w) {
146         context.enter(s);
147         windingLabels.put(s, w);
148     }
149     public void leaveContext() { context.exit(); }
150
151     public void doBreak(String JavaDoc label) {
152         Stmt target = context.getBreakTarget(label);
153         doJsrUntil(target);
154         emitJump((Label)breakLabels.get(target));
155     }
156     public void doContinue(String JavaDoc label) {
157         Stmt target = context.getContinueTarget(label);
158         doJsrUntil(target);
159         emitJump((Label)continueLabels.get(target));
160     }
161     private void doJsrUntil(Stmt target) {
162         for (Iterator JavaDoc i = context.getWindsUntil(target); i.hasNext(); ) {
163             emitJSR((Label)windingLabels.get(i.next()));
164         }
165     }
166     public void doReturn(Type t) {
167         for (Iterator JavaDoc i = context.getWindsUntil(null); i.hasNext(); ) {
168             WindingStmt w = (WindingStmt) i.next();
169             int rvl = w.getRetValLoc();
170             t.emitStore(this, rvl);
171             emitJSR((Label)windingLabels.get(w));
172             t.emitLoad(this, rvl);
173         }
174         t.emitReturn(this);
175     }
176
177     // ------------------------------
178
// local variable table stuff
179

180     // We handle local variables by using a Stack, and pushing and
181
// popping as appropriate. When we enter a block, for stmt, or
182
// catch block, we push a pair of null markers to indicate the
183
// block. When we leave a block, we pop down to those markers.
184
// The stack also contains varDec x label. Popping through a
185
// VarDec x label ends its scope. Pushing a VarDec x label enters
186
// its scope, with that label. Easy peasy.
187

188     // We're using java.util.Stack, but just it's stack-like
189
// operations. So this would work even if java.util.Sack
190
// encapsulated java.util.Vector, instead of making the mistake of
191
// extending it.
192

193     private Stack JavaDoc localVarStack = new Stack JavaDoc();
194
195     public void enterBlock() {
196         //System.err.println("CB/entering block");
197
localVarStack.push(null);
198         localVarStack.push(null);
199     }
200
201     public void enterVar(VarDec v) {
202         //System.err.println("CB/entering var " + v);
203
Label start = genAnchor();
204         emitLabel(start);
205         localVarStack.push(v);
206         localVarStack.push(start);
207     }
208
209     public void exitBlock() {
210         //System.err.println("CB/leaving block");
211
Label start = (Label) localVarStack.pop();
212         VarDec v = (VarDec) localVarStack.pop();
213         for (; v != null;
214              start = (Label) localVarStack.pop(),
215              v = (VarDec) localVarStack.pop()) {
216             //System.err.println(" of var " + v);
217
Label end = genAnchor();
218             emitLabel(end);
219             localVars = new LocalVar(start, end,
220                                       pool.addUtf8(v.getBytecodeId()),
221                                       pool.addUtf8(v.getDescriptor()),
222                                       v.getFrameLoc(),
223                                       localVars);
224         }
225     }
226
227     // the local vars themselves are stored as a list of four-element
228
// tuples, as we do the line number table later.
229

230     private static final class LocalVar {
231         Label start;
232         Label end;
233         Constant name;
234         Constant descriptor;
235         int index;
236         LocalVar next;
237         LocalVar(Label start,
238                  Label end,
239                  Constant name,
240                  Constant descriptor,
241                  int index,
242                  LocalVar next) {
243             this.start = start;
244             this.end = end;
245             this.name = name;
246             this.descriptor = descriptor;
247             this.index = index;
248             this.next = next;
249         }
250         public String JavaDoc toString() {
251             return "(" + start + " " + end + " " + name + " " + descriptor + " "
252                 + index + "):" + next;
253         }
254     }
255
256     private LocalVar localVars = null;
257
258     void createLocalAttribute() {
259         //System.err.println("CB/Creating");
260
//System.err.println(localVars);
261
// find the size
262
int size = 0;
263         for (LocalVar in = localVars; in != null; in = in.next) {
264             size++;
265         }
266         if (size == 0) return;
267         // create the arrays
268
Label[] starts = new Label[size];
269         Label[] ends = new Label[size];
270         Constant[] names = new Constant[size];
271         Constant[] descriptors = new Constant[size];
272         int[] indices = new int[size];
273         // fill them
274
LocalVar lvs = localVars;
275         int i = 0;
276         for (; lvs != null; i++, lvs = lvs.next) {
277             starts[i] = lvs.start;
278             ends[i] = lvs.end;
279             names[i] = lvs.name;
280             descriptors[i] = lvs.descriptor;
281             indices[i] = lvs.index;
282         }
283         // and create the attribute
284
attributes.addLocalVariableTableAttribute(starts, ends, names,
285                                                   descriptors, indices);
286     }
287
288     // ------------------------------
289
// line number table context
290

291     private static final class LineNumber {
292         ClassfileBuilder.SourceFile fileInfo;
293         Label pc;
294         int line;
295         LineNumber next;
296         LineNumber(ClassfileBuilder.SourceFile fileInfo, Label pc, int line, LineNumber next) {
297             this.fileInfo = fileInfo;
298             this.pc = pc;
299             this.line = line;
300             this.next = next;
301         }
302     }
303
304     LineNumber lineNumbers = null;
305
306     public void enterLocation(SourceLocation loc) {
307         //System.err.println("hiya: " + loc);
308
ClassfileBuilder.SourceFile fileInfo = cfb.getSourceFile(loc);
309         if (fileInfo == null) return; // why?
310
int currLine = loc.getBeginLine();
311         if (lineNumbers != null) {
312             if (currLine == -1) return; // hmm. This sounds dangerous.
313
if (currLine == lineNumbers.line && fileInfo == lineNumbers.fileInfo) return;
314         }
315         Label pc = genAnchor();
316         emitLabel(pc);
317         lineNumbers = new LineNumber(fileInfo, pc, currLine, lineNumbers);
318     }
319
320     void createLineAttribute() {
321         // This could be done in one pass with recursion.
322
// reverse, set aright, and get size.
323
int endPc = getEndPc();
324         int size = 0;
325         LineNumber in = lineNumbers;
326         LineNumber out = null;
327         // increment the line number according to the offset of its source file.
328
while (in != null) {
329             if (in.pc.getPc() >= endPc) {
330                 in = in.next;
331             } else {
332 // cfb.addLineNumber(in.line, in.fileInfo);
333
in.line += in.fileInfo.offset;
334                 LineNumber temp = in.next;
335                 in.next = out;
336                 out = in;
337                 in = temp;
338                 size++;
339             }
340         }
341         // create the arrays
342
Label[] pcs = new Label[size];
343         int[] lines = new int[size];
344         // fill them
345
for (int i = 0; i < size; i++, out = out.next) {
346             pcs[i] = out.pc;
347             lines[i] = out.line;
348         }
349         // and create the attribute
350
attributes.addLineNumberTableAttribute(pcs, lines);
351     }
352
353     // ------------------------------
354
// exception handlers
355

356     public void addHandler(Label start, Label end, Label handler, NameType exn) {
357         starts.add(start);
358         ends.add(end);
359         handlers.add(handler);
360         names.add((exn == null) ? null : pool.addClass(exn));
361     }
362
363     void compressExceptionTable() {
364         Iterator JavaDoc i = starts.iterator();
365         Iterator JavaDoc j = ends.iterator();
366         Iterator JavaDoc k = handlers.iterator();
367         Iterator JavaDoc l = names.iterator();
368         for (; i.hasNext(); ) {
369             if (((Label)i.next()).getPc() == ((Label)j.next()).getPc()) {
370                 k.next();
371                 l.next();
372                 i.remove();
373                 j.remove();
374                 k.remove();
375                 l.remove();
376             }
377         }
378     }
379
380     void writeExceptionTableTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
381         stream.writeShort((short)starts.size());
382         Iterator JavaDoc i = starts.iterator();
383         Iterator JavaDoc j = ends.iterator();
384         Iterator JavaDoc k = handlers.iterator();
385         Iterator JavaDoc l = names.iterator();
386         for (; i.hasNext(); ) {
387             stream.writeShort(((Label)i.next()).getPc());
388             stream.writeShort(((Label)j.next()).getPc());
389             stream.writeShort(((Label)k.next()).getPc());
390             Constant name = (Constant)l.next();
391             if (name == null) {
392                 stream.writeShort(0);
393             } else {
394                 name.writeIndex(stream);
395             }
396         }
397     }
398
399     // ------------------------------
400
// labels
401

402     JumpCode prevJump = null;
403
404     public void emitLabel(Label l) {
405         if (isResolved()) throw new RuntimeException JavaDoc("already resolved");
406         labels.add(l);
407         if (prevJump != null) {
408             if (prevJump.getDest() == l) {
409                 labels.addAll(prevJump.getLabels());
410                 codes.remove(codes.size() - 1);
411                 if (! codes.isEmpty()
412                         && (codes.get(codes.size() - 1) instanceof JumpCode)) {
413                     prevJump = (JumpCode) codes.get(codes.size() - 1);
414                 } else {
415                     prevJump = null;
416                 }
417             }
418         }
419     }
420
421     public Label genLabel() {
422         return new Label(false);
423     }
424     public Label genAnchor() {
425         return new Label(true);
426     }
427
428
429     // ------------------------------
430
// Codes
431

432     private void addCode(Code c, int stackDelta) {
433         addCode(c);
434         adjustStack(stackDelta);
435     }
436     private void addCode(Code c) {
437         if (isResolved()) {
438             throw new RuntimeException JavaDoc("already resolved");
439         }
440         for (Iterator JavaDoc i = labels.iterator(); i.hasNext(); ) {
441             ((Label) i.next()).setTarget(c);
442         }
443         c.index = codes.size();
444         labels.clear();
445         codes.add(c);
446         prevJump = null;
447     }
448
449     // ------------------------------
450
// assembly and output
451

452     public void resolve() {
453         if (isResolved()) {
454             throw new RuntimeException JavaDoc("already resolved");
455         }
456         if (! pool.isResolved()) {
457             throw new RuntimeException JavaDoc("pool not resolved yet");
458         }
459
460         addCode(new SentinelCode());
461         int len = codes.size();
462         Code[] a = new Code[len];
463         for (int i = 0; i < len; i++) {
464             a[i] = (Code) codes.get(i);
465         }
466         codea = a;
467         codes = null;
468
469         keelbackwards();
470
471         int pc = 0;
472         try {
473             for (int i = 0; i < len; i++) {
474                 if (DEBUG) System.err.print("(" + i + ") pc " + pc);
475                 Code c = a[i];
476                 pc = c.resolveBest(pc);
477                 if (DEBUG) System.err.println(" -> " + pc);
478             }
479
480             // XXX let's try writing to a dummy stream to make sure we
481
// can without generating a tooWideJumpException. This is
482
// fairly inefficient; it would be better to run through
483
// and just check jump/branch/etc codes.
484
DataOutputStream JavaDoc sink = new DataOutputStream JavaDoc(new OutputStream JavaDoc() {
485                     public void write(int b) {}
486                 });
487             try {
488                 for (int i = 0; i < len; i++) {
489                     a[i].writeTo(sink);
490                 }
491             } catch (IOException JavaDoc e) {}
492         } catch (TooWideJumpException e) {
493             pc = 0;
494             for (int i = 0; i < len; i++) {
495                 Code c = a[i];
496                 pc = c.resolveWorst(pc);
497             }
498         }
499         endPc = pc;
500         if (DEBUG) {
501             System.err.println(">>>>");
502             display(0, false);
503             System.err.println();
504
505             for (int i = 0; i < len; i++) {
506                 Code c = a[i];
507                 for (Iterator JavaDoc ii = c.getLabels().iterator(); ii.hasNext(); ) {
508                     if (((Label) ii.next()).getTarget() != c) {
509                         System.err.println("hi");
510                     }
511                 }
512             }
513         }
514         isResolvedFlag = true;
515
516         createLineAttribute();
517         createLocalAttribute();
518         compressExceptionTable();
519     }
520
521     private int endPc;
522     int getEndPc() {
523         if (! isResolvedFlag) throw new RuntimeException JavaDoc("not yet resolved");
524         return endPc;
525     }
526
527     static class TooWideJumpException extends RuntimeException JavaDoc {}
528
529     //!!! should clean this up
530
static final boolean DEBUG = false;
531     private void keelbackwards() {
532         if (DEBUG) {
533             isResolvedFlag = true;
534             System.err.println("---");
535             display(0, false);
536             System.err.println();
537             System.err.println(">>>");
538         }
539         Code[] a = codea;
540         // there's a sentinel at the end
541
Code next;
542         Code curr = a[a.length - 1];
543         for (int i = a.length - 2; i >= 0; i--) {
544             next = curr;
545             curr = a[i];
546             curr.resolve(next.getRealNext());
547             if (curr.jumps()) {
548                 next.notifyNonLive();
549             }
550         }
551         if (DEBUG) {
552             display(0, false);
553             System.err.println();
554         }
555     }
556
557     int getByteSize() {
558         return 2 + 2 + getCodeByteSize()
559             + getExnTableByteSize()
560             + attributes.getByteSize();
561     }
562     private int getCodeByteSize() {
563         return 4 + getEndPc();
564     }
565     private int getExnTableByteSize() {
566         return 2 + (8 * starts.size());
567     }
568
569     void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
570         if (! isResolved()) {
571             throw new RuntimeException JavaDoc("not yet resolved");
572         }
573         stream.writeShort((short) maxStack);
574         stream.writeShort((short) maxFrame);
575         writeCodeTo(stream);
576         writeExceptionTableTo(stream);
577         attributes.writeTo(stream);
578     }
579
580     private void writeCodeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
581         stream.writeInt(getEndPc());
582         Code[] a = codea;
583         for (int i = 0, len = a.length; i < len; i++) {
584             a[i].writeTo(stream);
585         }
586     }
587
588     // ------------------------------
589
// building methods
590

591     // jumps
592

593     public void emitJump(Label dest) {
594         JumpCode c = new JumpCode(dest);
595         addCode(c);
596         prevJump = c;
597     }
598
599     public void emitJSR(Label dest) {
600         addCode(new JsrCode(dest));
601     }
602
603     public void emitRET(int n) {
604         addCode(new FrameCode(RET, n), 0);
605     }
606
607     // switches
608

609     public void emitSwitch(int[] keys, Label[] cases, Label defaultCase) {
610         long min = keys[0];
611         long max = keys[keys.length - 1];
612
613         if ((1 + 1 + max - min + 1) // max + min + 1 word per (max - min + 1)
614
<=
615             (1 + keys.length * 2)) { // size + 2 words per entry
616
Label[] realCases = new Label[(int)(max - min + 1)];
617             for (int kv = (int)min, ki = 0, ci = 0, oi = 0; kv <= (int)max; kv++, oi++) {
618                 if (kv == keys[ki]) {
619                     realCases[oi] = cases[ci++];
620                     ki++;
621                 } else {
622                     realCases[oi] = defaultCase;
623                 }
624             }
625             addCode(new TableSwitchCode((int)min, (int)max, realCases, defaultCase), -1);
626
627         } else {
628             addCode(new LookupSwitchCode(keys, cases, defaultCase), -1);
629         }
630     }
631
632     // fields and methods
633

634     public void emitINVOKESTATIC(NameType nameType, String JavaDoc name,
635                                  String JavaDoc descriptor, int stackDelta) {
636         addCode(new PoolCode(INVOKESTATIC,
637                              pool.addMethodRef(nameType, name, descriptor)),
638                 stackDelta);
639     }
640     public void emitINVOKESPECIAL(NameType nameType, String JavaDoc name,
641                                  String JavaDoc descriptor, int stackDelta) {
642         addCode(new PoolCode(INVOKESPECIAL,
643                              pool.addMethodRef(nameType,
644                                                name, descriptor)),
645                 stackDelta);
646     }
647     public void emitINVOKEINTERFACE(NameType nameType, String JavaDoc name,
648                                     String JavaDoc descriptor, int stackDelta, int arglen) {
649         addCode(new InvokeInterfaceCode(pool.addInterfaceMethodRef(nameType,
650                                                                    name,
651                                                                    descriptor),
652                                         arglen),
653                 stackDelta);
654     }
655     public void emitINVOKEVIRTUAL(NameType nameType, String JavaDoc name,
656                                  String JavaDoc descriptor, int stackDelta) {
657         addCode(new PoolCode(INVOKEVIRTUAL,
658                              pool.addMethodRef(nameType,
659                                                name, descriptor)),
660                 stackDelta);
661     }
662     public void emitGETSTATIC(NameType nameType, String JavaDoc name,
663                               String JavaDoc descriptor, int stackDelta) {
664         addCode(new PoolCode(GETSTATIC,
665                              pool.addFieldRef(nameType,
666                                               name, descriptor)),
667                 stackDelta);
668     }
669     public void emitPUTSTATIC(NameType nameType, String JavaDoc name,
670                               String JavaDoc descriptor, int stackDelta) {
671         addCode(new PoolCode(PUTSTATIC,
672                              pool.addFieldRef(nameType,
673                                               name, descriptor)),
674                 stackDelta);
675     }
676     public void emitGETFIELD(NameType nameType, String JavaDoc name,
677                              String JavaDoc descriptor, int stackDelta) {
678         addCode(new PoolCode(GETFIELD,
679                              pool.addFieldRef(nameType,
680                                               name, descriptor)),
681                 stackDelta);
682     }
683     public void emitPUTFIELD(NameType nameType, String JavaDoc name,
684                              String JavaDoc descriptor, int stackDelta) {
685         addCode(new PoolCode(PUTFIELD,
686                              pool.addFieldRef(nameType,
687                                               name, descriptor)),
688                 stackDelta);
689     }
690
691     // pools
692

693     public void emitNEW(NameType nameType) {
694         addCode(new PoolCode(NEW, pool.addClass(nameType)), 1);
695     }
696     public void emitCHECKCAST(RefType refType) {
697         addCode(new PoolCode(CHECKCAST, pool.addClass(refType)));
698     }
699     public void emitINSTANCEOF(RefType refType) {
700         addCode(new PoolCode(INSTANCEOF, pool.addClass(refType)), 0);
701     }
702
703     // basics
704
public void emitIAND() { addCode(new BasicCode(IAND), -1); }
705     public void emitLAND() { addCode(new BasicCode(LAND), -2); }
706     public void emitNULL() { addCode(new BasicCode(ACONST_NULL), 1); }
707     public void emitI2L() { addCode(new BasicCode(I2L), 1); }
708     public void emitI2F() { addCode(new BasicCode(I2F), 0); }
709     public void emitI2D() { addCode(new BasicCode(I2D), 1); }
710     public void emitL2I() { addCode(new BasicCode(L2I), -1); }
711     public void emitL2F() { addCode(new BasicCode(L2F), -1); }
712     public void emitL2D() { addCode(new BasicCode(L2D), 0); }
713     public void emitF2I() { addCode(new BasicCode(F2I), 0); }
714     public void emitF2L() { addCode(new BasicCode(F2L), 1); }
715     public void emitF2D() { addCode(new BasicCode(F2D), 1); }
716     public void emitD2I() { addCode(new BasicCode(D2I), -1); }
717     public void emitD2L() { addCode(new BasicCode(D2L), 0); }
718     public void emitD2F() { addCode(new BasicCode(D2F), -1); }
719     public void emitI2B() { addCode(new BasicCode(I2B), 0); }
720     public void emitI2C() { addCode(new BasicCode(I2C), 0); }
721     public void emitI2S() { addCode(new BasicCode(I2S), 0); }
722     public void emitPOP() { addCode(new BasicCode(POP), -1); }
723     public void emitPOP2() { addCode(new BasicCode(POP2), -2); }
724     public void emitLCMP () { addCode(new BasicCode(LCMP), -3); }
725     public void emitFCMPL() { addCode(new BasicCode(FCMPL), -1); }
726     public void emitFCMPG() { addCode(new BasicCode(FCMPG), -1); }
727     public void emitDCMPL() { addCode(new BasicCode(DCMPL), -3); }
728     public void emitDCMPG() { addCode(new BasicCode(DCMPG), -3); }
729     public void emitNOP() { addCode(new BasicCode(NOP), 0); }
730     public void emitACONST_NULL() { addCode(new BasicCode(ACONST_NULL), 1); }
731     public void emitIALOAD() { addCode(new BasicCode(IALOAD), -1); }
732     public void emitLALOAD() { addCode(new BasicCode(LALOAD), 0); }
733     public void emitFALOAD() { addCode(new BasicCode(FALOAD), -1); }
734     public void emitDALOAD() { addCode(new BasicCode(DALOAD), 0); }
735     public void emitAALOAD() { addCode(new BasicCode(AALOAD), -1); }
736     public void emitBALOAD() { addCode(new BasicCode(BALOAD), -1); }
737     public void emitCALOAD() { addCode(new BasicCode(CALOAD), -1); }
738     public void emitSALOAD() { addCode(new BasicCode(SALOAD), -1); }
739     public void emitIASTORE() { addCode(new BasicCode(IASTORE), -3); }
740     public void emitLASTORE() { addCode(new BasicCode(LASTORE), -4); }
741     public void emitFASTORE() { addCode(new BasicCode(FASTORE), -3); }
742     public void emitDASTORE() { addCode(new BasicCode(DASTORE), -4); }
743     public void emitAASTORE() { addCode(new BasicCode(AASTORE), -3); }
744     public void emitBASTORE() { addCode(new BasicCode(BASTORE), -3); }
745     public void emitCASTORE() { addCode(new BasicCode(CASTORE), -3); }
746     public void emitSASTORE() { addCode(new BasicCode(SASTORE), -3); }
747     public void emitSWAP() { addCode(new BasicCode(SWAP), 0); }
748     public void emitIADD() { addCode(new BasicCode(IADD), -1); }
749     public void emitLADD() { addCode(new BasicCode(LADD), -2); }
750     public void emitFADD() { addCode(new BasicCode(FADD), -1); }
751     public void emitDADD() { addCode(new BasicCode(DADD), -2); }
752     public void emitISUB() { addCode(new BasicCode(ISUB), -1); }
753     public void emitLSUB() { addCode(new BasicCode(LSUB), -2); }
754     public void emitFSUB() { addCode(new BasicCode(FSUB), -1); }
755     public void emitDSUB() { addCode(new BasicCode(DSUB), -2); }
756     public void emitIMUL() { addCode(new BasicCode(IMUL), -1); }
757     public void emitLMUL() { addCode(new BasicCode(LMUL), -2); }
758     public void emitFMUL() { addCode(new BasicCode(FMUL), -1); }
759     public void emitDMUL() { addCode(new BasicCode(DMUL), -2); }
760     public void emitIDIV() { addCode(new BasicCode(IDIV), -1); }
761     public void emitLDIV() { addCode(new BasicCode(LDIV), -2); }
762     public void emitFDIV() { addCode(new BasicCode(FDIV), -1); }
763     public void emitDDIV() { addCode(new BasicCode(DDIV), -2); }
764     public void emitIREM() { addCode(new BasicCode(IREM), -1); }
765     public void emitLREM() { addCode(new BasicCode(LREM), -2); }
766     public void emitFREM() { addCode(new BasicCode(FREM), -1); }
767     public void emitDREM() { addCode(new BasicCode(DREM), -2); }
768     public void emitINEG() { addCode(new BasicCode(INEG), 0); }
769     public void emitLNEG() { addCode(new BasicCode(LNEG), 0); }
770     public void emitFNEG() { addCode(new BasicCode(FNEG), 0); }
771     public void emitDNEG() { addCode(new BasicCode(DNEG), 0); }
772     public void emitISHL() { addCode(new BasicCode(ISHL), -1); }
773     public void emitLSHL() { addCode(new BasicCode(LSHL), -1); }
774     public void emitISHR() { addCode(new BasicCode(ISHR), -1); }
775     public void emitLSHR() { addCode(new BasicCode(LSHR), -1); }
776     public void emitIUSHR() { addCode(new BasicCode(IUSHR), -1); }
777     public void emitLUSHR() { addCode(new BasicCode(LUSHR), -1); }
778     public void emitIOR() { addCode(new BasicCode(IOR), -1); }
779     public void emitLOR() { addCode(new BasicCode(LOR), -2); }
780     public void emitIXOR() { addCode(new BasicCode(IXOR), -1); }
781     public void emitLXOR() { addCode(new BasicCode(LXOR), -2); }
782     public void emitIRETURN() { addCode(new ReturnCode(IRETURN), -1); }
783     public void emitLRETURN() { addCode(new ReturnCode(LRETURN), -2); }
784     public void emitFRETURN() { addCode(new ReturnCode(FRETURN), -1); }
785     public void emitDRETURN() { addCode(new ReturnCode(DRETURN), -2); }
786     public void emitARETURN() { addCode(new ReturnCode(ARETURN), -1); }
787     public void emitRETURN() { addCode(new ReturnCode(RETURN), 0); }
788     public void emitARRAYLENGTH() { addCode(new BasicCode(ARRAYLENGTH), 0); }
789     public void emitATHROW() { addCode(new BasicCode(ATHROW), -1); }
790     public void emitMONITORENTER(){ addCode(new BasicCode(MONITORENTER),-1); }
791     public void emitMONITOREXIT() { addCode(new BasicCode(MONITOREXIT), -1); }
792     public void emitDUP() { addCode(new BasicCode(DUP), 1); }
793     public void emitDUP_X1() { addCode(new BasicCode(DUP_X1), 1); }
794     public void emitDUP_X2() { addCode(new BasicCode(DUP_X2), 1); }
795     public void emitDUP2() { addCode(new BasicCode(DUP2), 2); }
796     public void emitDUP2_X1() { addCode(new BasicCode(DUP2_X1), 2); }
797     public void emitDUP2_X2() { addCode(new BasicCode(DUP2_X2), 2); }
798
799     // branches
800

801     public void emitIFEQ(Label tdest, Label fdest) {
802         addCode(new BranchCode(IFEQ, IFNE, tdest, fdest), -1);
803     }
804     public void emitIFNE(Label tdest, Label fdest) {
805         addCode(new BranchCode(IFNE, IFEQ, tdest, fdest), -1);
806     }
807     public void emitIFLT(Label tdest, Label fdest) {
808         addCode(new BranchCode(IFLT, IFGE, tdest, fdest), -1);
809     }
810     public void emitIFGE(Label tdest, Label fdest) {
811         addCode(new BranchCode(IFGE, IFLT, tdest, fdest), -1);
812     }
813     public void emitIFGT(Label tdest, Label fdest) {
814         addCode(new BranchCode(IFGT, IFLE, tdest, fdest), -1);
815     }
816     public void emitIFLE(Label tdest, Label fdest) {
817         addCode(new BranchCode(IFLE, IFGT, tdest, fdest), -1);
818     }
819
820     public void emitIF_ICMPEQ(Label tdest, Label fdest) {
821         addCode(new BranchCode(IF_ICMPEQ, IF_ICMPNE, tdest, fdest), -2);
822     }
823     public void emitIF_ICMPNE(Label tdest, Label fdest) {
824         addCode(new BranchCode(IF_ICMPNE, IF_ICMPEQ, tdest, fdest), -2);
825     }
826     public void emitIF_ICMPLT(Label tdest, Label fdest) {
827         addCode(new BranchCode(IF_ICMPLT, IF_ICMPGE, tdest, fdest), -2);
828     }
829     public void emitIF_ICMPGE(Label tdest, Label fdest) {
830         addCode(new BranchCode(IF_ICMPGE, IF_ICMPLT, tdest, fdest), -2);
831     }
832     public void emitIF_ICMPGT(Label tdest, Label fdest) {
833         addCode(new BranchCode(IF_ICMPGT, IF_ICMPLE, tdest, fdest), -2);
834     }
835     public void emitIF_ICMPLE(Label tdest, Label fdest) {
836         addCode(new BranchCode(IF_ICMPLE, IF_ICMPGT, tdest, fdest), -2);
837     }
838
839     public void emitIF_ACMPEQ(Label tdest, Label fdest) {
840         addCode(new BranchCode(IF_ACMPEQ, IF_ACMPNE, tdest, fdest), -2);
841     }
842     public void emitIF_ACMPNE(Label tdest, Label fdest) {
843         addCode(new BranchCode(IF_ACMPNE, IF_ACMPEQ, tdest, fdest), -2);
844     }
845     public void emitIFNULL(Label tdest, Label fdest) {
846         addCode(new BranchCode(IFNULL, IFNONNULL, tdest, fdest), -1);
847     }
848     public void emitIFNONNULL(Label tdest, Label fdest) {
849         addCode(new BranchCode(IFNONNULL, IFNULL, tdest, fdest), -1);
850     }
851
852     // constants
853

854     public void emitIntConstant(int val) {
855         Code code;
856         switch (val) {
857         case -1: code = new BasicCode(ICONST_M1); break;
858         case 0: code = new BasicCode(ICONST_0); break;
859         case 1: code = new BasicCode(ICONST_1); break;
860         case 2: code = new BasicCode(ICONST_2); break;
861         case 3: code = new BasicCode(ICONST_3); break;
862         case 4: code = new BasicCode(ICONST_4); break;
863         case 5: code = new BasicCode(ICONST_5); break;
864         default:
865             if (Asserts.isByte(val)) {
866                 code = new ByteCode(BIPUSH, (byte)val);
867             } else if (Asserts.isShort(val)) {
868                 code = new ShortCode(SIPUSH, (short)val);
869             } else {
870                 code = new LDCCode(pool.addInt(val));
871             }
872             break;
873         }
874         addCode(code, 1);
875     }
876
877     public void emitLongConstant(long val) {
878         Code code;
879         if (val == 0L) code = new BasicCode(LCONST_0);
880         else if (val == 1L) code = new BasicCode(LCONST_1);
881         else code = new PoolCode(LDC2_W, pool.addLong(val));
882         addCode(code, 2);
883     }
884
885     public void emitFloatConstant(float val) {
886         Code code;
887         if (val == 0.0f) {
888             if ((1 / val) > 0) {
889                 code = new BasicCode(FCONST_0);
890             } else {
891                 code = new LDCCode(pool.addFloat(val));
892             }
893         }
894         else if (val == 1.0f) code = new BasicCode(FCONST_1);
895         else if (val == 2.0f) code = new BasicCode(FCONST_2);
896         else code = new LDCCode(pool.addFloat(val));
897         addCode(code, 1);
898     }
899
900     public void emitDoubleConstant(double val) {
901         Code code;
902         if (val == 0.0D) {
903             if ((1 / val) > 0) {
904                 code = new BasicCode(DCONST_0);
905             } else {
906                 code = new PoolCode(LDC2_W, pool.addDouble(val));
907             }
908         }
909         else if (val == 1.0D) code = new BasicCode(DCONST_1);
910         else code = new PoolCode(LDC2_W, pool.addDouble(val));
911         addCode(code, 2);
912     }
913
914     public void emitStringConstant(String JavaDoc val) {
915         addCode(new LDCCode(pool.addString(val)), 1);
916     }
917
918     // arrays
919

920     public void emitNEWARRAY(int tyIndex) {
921         addCode(new ByteCode(NEWARRAY, (byte)tyIndex), 0);
922     }
923
924     public void emitANEWARRAY(RefType componentType) {
925         addCode(new PoolCode(ANEWARRAY, pool.addClass(componentType)), 0);
926     }
927
928     public void emitMULTIANEWARRAY(ArrayType arrayType, int dimCount) {
929         addCode(new PoolByteCode(MULTIANEWARRAY,
930                                  pool.addClass(arrayType),
931                                  (byte)dimCount),
932                 -(dimCount - 1));
933     }
934
935     // loads and stores
936

937     private final byte[] aloads = { ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ALOAD };
938     private final byte[] iloads = { ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, ILOAD };
939     private final byte[] lloads = { LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LLOAD };
940     private final byte[] floads = { FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FLOAD };
941     private final byte[] dloads = { DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DLOAD };
942
943     private final byte[] astores = { ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, ASTORE };
944     private final byte[] istores = { ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISTORE };
945     private final byte[] lstores = { LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSTORE };
946     private final byte[] fstores = { FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSTORE };
947     private final byte[] dstores = { DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSTORE };
948
949     public void emitALOAD(int n) { emitFrameCode(aloads, n, 1); }
950     public void emitILOAD(int n) { emitFrameCode(iloads, n, 1); }
951     public void emitLLOAD(int n) { emitFrameCode(lloads, n, 2); }
952     public void emitFLOAD(int n) { emitFrameCode(floads, n, 1); }
953     public void emitDLOAD(int n) { emitFrameCode(dloads, n, 2); }
954
955     public void emitASTORE(int n) { emitFrameCode(astores, n, -1); }
956     public void emitISTORE(int n) { emitFrameCode(istores, n, -1); }
957     public void emitLSTORE(int n) { emitFrameCode(lstores, n, -2); }
958     public void emitFSTORE(int n) { emitFrameCode(fstores, n, -1); }
959     public void emitDSTORE(int n) { emitFrameCode(dstores, n, -2); }
960
961     public void emitFrameCode(byte[] insts, int n, int delta) {
962         if (n <= 3) addCode(new BasicCode(insts[n]), delta);
963         else addCode(new FrameCode(insts[4], n), delta);
964     }
965
966     // iinc
967

968     public void emitIINC(int n, int incr) {
969         addCode(new IncCode(n, incr), 0);
970     }
971
972     // ------------------------------
973
// ------------------------------
974
// debugging
975

976     public String JavaDoc toString() {
977         return "(st/fr " + maxStack + " " + maxFrame + ") " +
978             attributes;
979     }
980
981     public void emitStackSize() {
982         addCode(new BasicCode(NOP));
983         addCode(new ByteCode(BIPUSH, (byte)getStackSize()));
984         addCode(new BasicCode(POP));
985         addCode(new BasicCode(NOP));
986     }
987
988     int labelCount = 0;
989     public void displayInstructions(int indent) {
990         List JavaDoc codes = (isResolved())
991             ? Arrays.asList(codea)
992             : this.codes;
993         for (int i = 0, len = codes.size() - 1; i < len; i++) {
994             Code c = (Code) codes.get(i);
995             if (! c.isActive()) continue;
996             between(indent, false);
997             if (DEBUG) System.err.print("(" + i + ") ");
998             if (c.getLabels().size() != 0) {
999                 if (DEBUG) {
1000                    for (Iterator JavaDoc ii = c.getLabels().iterator(); ii.hasNext(); ) {
1001                        System.err.print(ii.next() + " ");
1002                    }
1003                } else {
1004                    String JavaDoc s = c.getLabels().get(0) + " ";
1005                    System.err.print(s);
1006                    for (int p = 4 - s.length(); p > 0; p--) {
1007                        System.err.print(" ");
1008                    }
1009                }
1010            } else {
1011                System.err.print(" ");
1012            }
1013            System.err.print(c);
1014        }
1015        for (int i = 0, len = starts.size(); i < len; i++) {
1016            between(indent, false);
1017            String JavaDoc name = (names.get(i) == null)
1018                ? "any"
1019                : names.get(i).toString();
1020            System.err.print("(throwing " + name
1021                               + " from " + starts.get(i)
1022                               + " to " + ends.get(i)
1023                               + " goto " + handlers.get(i) + ")");
1024        }
1025    }
1026
1027    public void display(int indent, boolean inline) {
1028        System.err.print("(stack " + maxStack + ") (locals " + maxFrame + ")");
1029        between(indent, inline);
1030        attributes.display(indent, inline);
1031        if (! inline) {
1032            displayInstructions(indent);
1033        }
1034    }
1035
1036    static void between(int indent, boolean inline) {
1037        if (inline) {
1038            System.err.print(" ");
1039        } else {
1040            System.err.println();
1041            for (int s=indent; s >= 0; s--) System.err.print(" ");
1042        }
1043    }
1044
1045    // ------------------------------
1046
// ------------------------------
1047
// classes
1048

1049    static class SentinelCode extends Code {
1050        int resolveBest(int pc) { setPc(pc); return pc; }
1051        void writeTo(DataOutputStream JavaDoc stream) {}
1052        public String JavaDoc toString() { return "SENTINEL"; }
1053        boolean isActive() { return false; }
1054    }
1055
1056    static class BranchCode extends Code {
1057        byte tcode, fcode;
1058        Label tdest, fdest;
1059        BranchCode(byte tcode, byte fcode, Label tdest, Label fdest) {
1060            this.tcode = tcode; this.tdest = tdest;
1061            this.fcode = fcode; this.fdest = fdest;
1062        }
1063
1064        boolean oneArmed;
1065        boolean arm;
1066        void resolve(Code next) {
1067            if (tdest.getTarget() == next) {
1068                oneArmed = true;
1069                arm = false;
1070            } else if (fdest.getTarget() == next) {
1071                oneArmed = true;
1072                arm = true;
1073            } else {
1074                oneArmed = false;
1075            }
1076        }
1077
1078        boolean jumps() { return true; }
1079
1080        boolean small = true;
1081        int resolveBest(int pc) { this.pc = pc; return pc + (oneArmed ? 3 : 6); }
1082        int resolveWorst(int pc) { small = false; this.pc = pc; return pc + (oneArmed ? 8 : 13); }
1083
1084        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1085            if (small) {
1086                if (! oneArmed) {
1087                    stream.writeByte(tcode);
1088                    tdest.writeRelativeShort(pc, stream);
1089                    stream.writeByte(GOTO);
1090                    fdest.writeRelativeShort(pc + 3, stream);
1091                } else if (arm) {
1092                    // branch on true code, fallthrough on false code
1093
stream.writeByte(tcode);
1094                    tdest.writeRelativeShort(pc, stream);
1095                } else {
1096                    stream.writeByte(fcode);
1097                    fdest.writeRelativeShort(pc, stream);
1098                }
1099            } else {
1100                if (! oneArmed) {
1101                    stream.writeByte(tcode);
1102                    stream.writeShort(8);
1103                    stream.writeByte(GOTO_W);
1104                    fdest.writeRelativeInt(pc + 3, stream);
1105                    stream.writeByte(GOTO_W);
1106                    tdest.writeRelativeInt(pc + 8, stream);
1107                } else if (arm) {
1108                    // branch on true code, fallthrough on false code
1109
stream.writeByte(fcode);
1110                    stream.writeShort(8);
1111                    stream.writeByte(GOTO_W);
1112                    tdest.writeRelativeInt(pc + 3, stream);
1113                } else {
1114                    stream.writeByte(tcode);
1115                    stream.writeShort(8);
1116                    stream.writeByte(GOTO_W);
1117                    fdest.writeRelativeInt(pc + 3, stream);
1118                }
1119            }
1120        }
1121
1122        public String JavaDoc toString() {
1123            if (! oneArmed) {
1124                return debugString(tcode) + " " + tdest + " else " + fdest;
1125            } else if (arm) {
1126                return debugString(tcode) + " " + tdest + " ";
1127            } else {
1128                return debugString(fcode) + " " + fdest + " ";
1129            }
1130        }
1131    }
1132
1133    static class JumpCode extends Code {
1134        boolean active = true;
1135        boolean isActive() { return active; }
1136        Label dest;
1137        JumpCode(Label dest) { this.dest = dest; }
1138        Label getDest() { return dest; }
1139        void setDest(Label dest) { this.dest = dest; }
1140
1141        boolean small = true;
1142        int resolveBest(int pc) { this.pc = pc; return (active) ? (pc + 3) : pc; }
1143        int resolveWorst(int pc) {
1144            small = false; this.pc = pc;
1145            return (active) ? (pc + 5) : pc;
1146        }
1147        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1148            if (! active) return;
1149            if (small) {
1150                stream.writeByte(GOTO);
1151                dest.writeRelativeShort(pc, stream);
1152            } else {
1153                stream.writeByte(GOTO_W);
1154                dest.writeRelativeInt(pc, stream);
1155            }
1156        }
1157        public String JavaDoc toString() {
1158            return "GOTO " + dest;
1159        }
1160        boolean jumps() { return active; }
1161
1162        void notifyNonLive() {
1163            active = false;
1164        }
1165        Code getRealNext() {
1166            return (active) ? this : dest.getTarget();
1167        }
1168        void resolve(Code next) {
1169            Code target = dest.getTarget();
1170            if (target != this) {
1171                for (Iterator JavaDoc i = getLabels().iterator(); i.hasNext(); ) {
1172                    Label l = (Label) i.next();
1173                    if (! l.isAnchored()) {
1174                        i.remove();
1175                        l.setTarget(target);
1176                    }
1177                }
1178            }
1179            if (next == target) {
1180                active = false;
1181            }
1182        }
1183    }
1184
1185    static class JsrCode extends Code {
1186        Label dest;
1187        JsrCode(Label dest) { this.dest = dest; }
1188        Label getDest() { return dest; }
1189
1190        int resolveBest(int pc) { this.pc = pc; return pc + 3; }
1191        int resolveWorst(int pc) { small = false; this.pc = pc; return pc + 5; }
1192
1193        boolean small = true;
1194        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1195            if (small) {
1196                stream.writeByte(JSR);
1197                dest.writeRelativeShort(pc, stream);
1198            } else {
1199                stream.writeByte(JSR_W);
1200                dest.writeRelativeInt(pc, stream);
1201            }
1202        }
1203
1204        public String JavaDoc toString() {
1205            return "JSR " + dest;
1206        }
1207    }
1208
1209    static class IncCode extends Code {
1210        int loc, val;
1211        int size;
1212        IncCode(int loc, int val) {
1213            this.loc = loc; this.val = val;
1214            size = (Asserts.isUByte(loc) && Asserts.isByte(val)) ? 3 : 6;
1215        }
1216        int resolveBest(int pc) { this.pc = pc; return pc + size; }
1217
1218        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1219            if (size == 6) {
1220                stream.writeByte(WIDE);
1221                stream.writeByte(IINC);
1222                stream.writeShort(loc);
1223                stream.writeShort(val);
1224            } else {
1225                stream.writeByte(IINC);
1226                stream.writeByte(loc);
1227                stream.writeByte(val);
1228
1229            }
1230        }
1231        public String JavaDoc toString() {
1232            return ((size == 6) ? "WIDE IINC " : "IINC ")
1233                + loc + " " + val;
1234        }
1235    }
1236
1237    static class FrameCode extends Code {
1238        byte code;
1239        int loc;
1240        int size;
1241        FrameCode(byte code, int loc) {
1242            this.code = code; this.loc = loc;
1243            size = Asserts.isUByte(loc) ? 2 : 4;
1244        }
1245        int resolveBest(int pc) { this.pc = pc; return pc + size; }
1246
1247        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1248            if (size == 4) {
1249                stream.writeByte(WIDE);
1250                stream.writeByte(code);
1251                stream.writeShort(loc);
1252            } else {
1253                stream.writeByte(code);
1254                stream.writeByte(loc);
1255            }
1256        }
1257        public String JavaDoc toString() {
1258            return ((size == 4) ? "WIDE " : "")
1259                + debugString(code) + " " + loc;
1260        }
1261    }
1262
1263    static class BasicCode extends Code {
1264        byte code;
1265        BasicCode(byte code) { this.code = code; }
1266
1267        int resolveBest(int pc) { this.pc = pc; return pc + 1; }
1268        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1269            stream.writeByte(code);
1270        }
1271        public String JavaDoc toString() {
1272            return debugString(code);
1273        }
1274    }
1275
1276    static class ReturnCode extends BasicCode {
1277        ReturnCode(byte code) { super(code); }
1278        boolean jumps() { return true; }
1279    }
1280
1281    static class ByteCode extends Code {
1282        byte code;
1283        byte data;
1284        ByteCode(byte code, byte data) {
1285            this.code = code; this.data = data;
1286        }
1287
1288        int resolveBest(int pc) { this.pc = pc; return pc + 2; }
1289        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1290            stream.writeByte(code);
1291            stream.writeByte(data);
1292        }
1293        public String JavaDoc toString() {
1294            return debugString(code) + " " + data;
1295        }
1296    }
1297
1298    static class ShortCode extends Code {
1299        byte code;
1300        short data;
1301        ShortCode(byte code, short data) {
1302            this.code = code; this.data = data;
1303        }
1304
1305        int resolveBest(int pc) { this.pc = pc; return pc + 3; }
1306        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1307            stream.writeByte(code);
1308            stream.writeShort(data);
1309        }
1310        public String JavaDoc toString() {
1311            return debugString(code) + " " + data;
1312        }
1313    }
1314
1315    static class PoolCode extends Code {
1316        byte code;
1317        Constant constant;
1318        PoolCode(byte code, Constant constant) {
1319            this.code = code; this.constant = constant;
1320        }
1321        int resolveBest(int pc) {
1322            this.pc = pc;
1323            return pc + 3;
1324        }
1325        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1326            stream.writeByte(code);
1327            constant.writeIndex(stream);
1328        }
1329        public String JavaDoc toString() {
1330            return debugString(code) + " " + constant;
1331        }
1332    }
1333
1334    static class InvokeInterfaceCode extends Code {
1335        Constant constant;
1336        int arglen;
1337        InvokeInterfaceCode(Constant constant, int arglen) {
1338            this.constant = constant;
1339            this.arglen = arglen;
1340        }
1341        int resolveBest(int pc) {
1342            this.pc = pc;
1343            return pc + 5;
1344        }
1345        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1346            stream.writeByte(INVOKEINTERFACE);
1347            constant.writeIndex(stream);
1348            stream.writeByte((byte)arglen);
1349            stream.writeByte(0);
1350        }
1351        public String JavaDoc toString() {
1352            return "INVOKEINTERFACE (args " + arglen + ") " + constant;
1353        }
1354    }
1355
1356    static class LDCCode extends Code {
1357        Constant constant;
1358        LDCCode(Constant constant) {
1359            this.constant = constant;
1360            constant.makePopular(); // popular constants are more likely to be LDCs rather than LDC_Ws
1361
}
1362        int resolveBest(int pc) {
1363            this.pc = pc; return pc + (Asserts.isUByte(constant.getIndex()) ? 2 : 3);
1364        }
1365        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1366            if (Asserts.isUByte(constant.getIndex())) {
1367                stream.writeByte(LDC);
1368                constant.writeBriefIndex(stream);
1369            } else {
1370                stream.writeByte(LDC_W);
1371                constant.writeIndex(stream);
1372            }
1373        }
1374        public String JavaDoc toString() {
1375            return "LDC " + constant + (Asserts.isUByte(constant.getIndex()) ? "" : " (!!WIDE!!)");
1376        }
1377    }
1378
1379    static class PoolByteCode extends Code { // multiNewArray
1380
byte code;
1381        Constant constant;
1382        byte data;
1383        PoolByteCode(byte code, Constant constant, byte data) {
1384            this.code = code; this.constant = constant; this.data = data;
1385        }
1386        int resolveBest(int pc) { this.pc = pc; return pc + 4; }
1387        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1388            stream.writeByte(code);
1389            constant.writeIndex(stream);
1390            stream.writeByte(data);
1391        }
1392        public String JavaDoc toString() {
1393            return debugString(code) + " " + constant + " " + data;
1394        }
1395    }
1396
1397    public static class TableSwitchCode extends Code {
1398        int padBytes = 0;
1399        int min;
1400        int max;
1401        Label[] cases;
1402        Label defaultCase;
1403        TableSwitchCode(int min, int max, Label[] cases, Label defaultCase) {
1404            this.min = min; this.max = max;
1405            this.cases = cases; this.defaultCase = defaultCase;
1406        }
1407        int resolveBest(int pc) {
1408            this.pc = pc;
1409            padBytes = (-pc) % 4 + 3;
1410            return pc + 1 + padBytes + 4 + 4 + 4 + (4 * cases.length);
1411        }
1412        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1413            stream.writeByte(TABLESWITCH);
1414            for (int i = padBytes; i > 0; i--) {
1415                stream.writeByte(0);
1416            }
1417            defaultCase.writeRelativeInt(pc, stream);
1418            stream.writeInt(min);
1419            stream.writeInt(max);
1420            for (int i = 0; i < cases.length; i++) {
1421                cases[i].writeRelativeInt(pc, stream);
1422            }
1423        }
1424        public String JavaDoc toString() {
1425            return "tableswitch";
1426        }
1427
1428        boolean jumps() { return true; }
1429    }
1430
1431    public static class LookupSwitchCode extends Code {
1432        int padBytes = 0;
1433        int[] keys;
1434        Label[] cases;
1435        Label defaultCase;
1436        LookupSwitchCode(int[] keys, Label[] cases, Label defaultCase) {
1437            this.keys = keys; this.cases = cases;
1438            this.defaultCase = defaultCase;
1439        }
1440        int resolveBest(int pc) {
1441            this.pc = pc;
1442            padBytes = (-pc) % 4 + 3;
1443            return pc + 1 + padBytes + 4 + 4 + (8 * cases.length);
1444        }
1445        void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
1446            stream.writeByte(LOOKUPSWITCH);
1447            for (int i = padBytes; i > 0; i--) {
1448                stream.writeByte(0);
1449            }
1450            defaultCase.writeRelativeInt(pc, stream);
1451            stream.writeInt(cases.length);
1452            for (int i = 0; i < cases.length; i++) {
1453                stream.writeInt(keys[i]);
1454                cases[i].writeRelativeInt(pc, stream);
1455            }
1456        }
1457        public String JavaDoc toString() {
1458            return "lookupswitch";
1459        }
1460        boolean jumps() { return true; }
1461    }
1462
1463    // ------------------------------
1464
// constants
1465

1466    // BasicCode
1467
protected static final byte NOP = (byte) 0x00;
1468    protected static final byte ACONST_NULL = (byte) 0x01;
1469    protected static final byte ICONST_M1 = (byte) 0x02;
1470    protected static final byte ICONST_0 = (byte) 0x03;
1471    protected static final byte ICONST_1 = (byte) 0x04;
1472    protected static final byte ICONST_2 = (byte) 0x05;
1473    protected static final byte ICONST_3 = (byte) 0x06;
1474    protected static final byte ICONST_4 = (byte) 0x07;
1475    protected static final byte ICONST_5 = (byte) 0x08;
1476    protected static final byte LCONST_0 = (byte) 0x09;
1477    protected static final byte LCONST_1 = (byte) 0x0a;
1478    protected static final byte FCONST_0 = (byte) 0x0b;
1479    protected static final byte FCONST_1 = (byte) 0x0c;
1480    protected static final byte FCONST_2 = (byte) 0x0d;
1481    protected static final byte DCONST_0 = (byte) 0x0e;
1482    protected static final byte DCONST_1 = (byte) 0x0f;
1483    protected static final byte ILOAD_0 = (byte) 0x1a;
1484    protected static final byte ILOAD_1 = (byte) 0x1b;
1485    protected static final byte ILOAD_2 = (byte) 0x1c;
1486    protected static final byte ILOAD_3 = (byte) 0x1d;
1487    protected static final byte LLOAD_0 = (byte) 0x1e;
1488    protected static final byte LLOAD_1 = (byte) 0x1f;
1489    protected static final byte LLOAD_2 = (byte) 0x20;
1490    protected static final byte LLOAD_3 = (byte) 0x21;
1491    protected static final byte FLOAD_0 = (byte) 0x22;
1492    protected static final byte FLOAD_1 = (byte) 0x23;
1493    protected static final byte FLOAD_2 = (byte) 0x24;
1494    protected static final byte FLOAD_3 = (byte) 0x25;
1495    protected static final byte DLOAD_0 = (byte) 0x26;
1496    protected static final byte DLOAD_1 = (byte) 0x27;
1497    protected static final byte DLOAD_2 = (byte) 0x28;
1498    protected static final byte DLOAD_3 = (byte) 0x29;
1499    protected static final byte ALOAD_0 = (byte) 0x2a;
1500    protected static final byte ALOAD_1 = (byte) 0x2b;
1501    protected static final byte ALOAD_2 = (byte) 0x2c;
1502    protected static final byte ALOAD_3 = (byte) 0x2d;
1503    protected static final byte IALOAD = (byte) 0x2e;
1504    protected static final byte LALOAD = (byte) 0x2f;
1505    protected static final byte FALOAD = (byte) 0x30;
1506    protected static final byte DALOAD = (byte) 0x31;
1507    protected static final byte AALOAD = (byte) 0x32;
1508    protected static final byte BALOAD = (byte) 0x33;
1509    protected static final byte CALOAD = (byte) 0x34;
1510    protected static final byte SALOAD = (byte) 0x35;
1511    protected static final byte ISTORE_0 = (byte) 0x3b;
1512    protected static final byte ISTORE_1 = (byte) 0x3c;
1513    protected static final byte ISTORE_2 = (byte) 0x3d;
1514    protected static final byte ISTORE_3 = (byte) 0x3e;
1515    protected static final byte LSTORE_0 = (byte) 0x3f;
1516    protected static final byte LSTORE_1 = (byte) 0x40;
1517    protected static final byte LSTORE_2 = (byte) 0x41;
1518    protected static final byte LSTORE_3 = (byte) 0x42;
1519    protected static final byte FSTORE_0 = (byte) 0x43;
1520    protected static final byte FSTORE_1 = (byte) 0x44;
1521    protected static final byte FSTORE_2 = (byte) 0x45;
1522    protected static final byte FSTORE_3 = (byte) 0x46;
1523    protected static final byte DSTORE_0 = (byte) 0x47;
1524    protected static final byte DSTORE_1 = (byte) 0x48;
1525    protected static final byte DSTORE_2 = (byte) 0x49;
1526    protected static final byte DSTORE_3 = (byte) 0x4a;
1527    protected static final byte ASTORE_0 = (byte) 0x4b;
1528    protected static final byte ASTORE_1 = (byte) 0x4c;
1529    protected static final byte ASTORE_2 = (byte) 0x4d;
1530    protected static final byte ASTORE_3 = (byte) 0x4e;
1531    protected static final byte IASTORE = (byte) 0x4f;
1532    protected static final byte LASTORE = (byte) 0x50;
1533    protected static final byte FASTORE = (byte) 0x51;
1534    protected static final byte DASTORE = (byte) 0x52;
1535    protected static final byte AASTORE = (byte) 0x53;
1536    protected static final byte BASTORE = (byte) 0x54;
1537    protected static final byte CASTORE = (byte) 0x55;
1538    protected static final byte SASTORE = (byte) 0x56;
1539    protected static final byte POP = (byte) 0x57;
1540    protected static final byte POP2 = (byte) 0x58;
1541    protected static final byte DUP = (byte) 0x59;
1542    protected static final byte DUP_X1 = (byte) 0x5a;
1543    protected static final byte DUP_X2 = (byte) 0x5b;
1544    protected static final byte DUP2 = (byte) 0x5c;
1545    protected static final byte DUP2_X1 = (byte) 0x5d;
1546    protected static final byte DUP2_X2 = (byte) 0x5e;
1547    protected static final byte SWAP = (byte) 0x5f;
1548    protected static final byte IADD = (byte) 0x60;
1549    protected static final byte LADD = (byte) 0x61;
1550    protected static final byte FADD = (byte) 0x62;
1551    protected static final byte DADD = (byte) 0x63;
1552    protected static final byte ISUB = (byte) 0x64;
1553    protected static final byte LSUB = (byte) 0x65;
1554    protected static final byte FSUB = (byte) 0x66;
1555    protected static final byte DSUB = (byte) 0x67;
1556    protected static final byte IMUL = (byte) 0x68;
1557    protected static final byte LMUL = (byte) 0x69;
1558    protected static final byte FMUL = (byte) 0x6a;
1559    protected static final byte DMUL = (byte) 0x6b;
1560    protected static final byte IDIV = (byte) 0x6c;
1561    protected static final byte LDIV = (byte) 0x6d;
1562    protected static final byte FDIV = (byte) 0x6e;
1563    protected static final byte DDIV = (byte) 0x6f;
1564    protected static final byte IREM = (byte) 0x70;
1565    protected static final byte LREM = (byte) 0x71;
1566    protected static final byte FREM = (byte) 0x72;
1567    protected static final byte DREM = (byte) 0x73;
1568    protected static final byte INEG = (byte) 0x74;
1569    protected static final byte LNEG = (byte) 0x75;
1570    protected static final byte FNEG = (byte) 0x76;
1571    protected static final byte DNEG = (byte) 0x77;
1572    protected static final byte ISHL = (byte) 0x78;
1573    protected static final byte LSHL = (byte) 0x79;
1574    protected static final byte ISHR = (byte) 0x7a;
1575    protected static final byte LSHR = (byte) 0x7b;
1576    protected static final byte IUSHR = (byte) 0x7c;
1577    protected static final byte LUSHR = (byte) 0x7d;
1578    protected static final byte IAND = (byte) 0x7e;
1579    protected static final byte LAND = (byte) 0x7f;
1580    protected static final byte IOR = (byte) 0x80;
1581    protected static final byte LOR = (byte) 0x81;
1582    protected static final byte IXOR = (byte) 0x82;
1583    protected static final byte LXOR = (byte) 0x83;
1584    protected static final byte I2L = (byte) 0x85;
1585    protected static final byte I2F = (byte) 0x86;
1586    protected static final byte I2D = (byte) 0x87;
1587    protected static final byte L2I = (byte) 0x88;
1588    protected static final byte L2F = (byte) 0x89;
1589    protected static final byte L2D = (byte) 0x8a;
1590    protected static final byte F2I = (byte) 0x8b;
1591    protected static final byte F2L = (byte) 0x8c;
1592    protected static final byte F2D = (byte) 0x8d;
1593    protected static final byte D2I = (byte) 0x8e;
1594    protected static final byte D2L = (byte) 0x8f;
1595    protected static final byte D2F = (byte) 0x90;
1596    protected static final byte I2B = (byte) 0x91;
1597    protected static final byte I2C = (byte) 0x92;
1598    protected static final byte I2S = (byte) 0x93;
1599    protected static final byte LCMP = (byte) 0x94;
1600    protected static final byte FCMPL = (byte) 0x95;
1601    protected static final byte FCMPG = (byte) 0x96;
1602    protected static final byte DCMPL = (byte) 0x97;
1603    protected static final byte DCMPG = (byte) 0x98;
1604    protected static final byte IRETURN = (byte) 0xac;
1605    protected static final byte LRETURN = (byte) 0xad;
1606    protected static final byte FRETURN = (byte) 0xae;
1607    protected static final byte DRETURN = (byte) 0xaf;
1608    protected static final byte ARETURN = (byte) 0xb0;
1609    protected static final byte RETURN = (byte) 0xb1;
1610    protected static final byte ARRAYLENGTH = (byte) 0xbe;
1611    protected static final byte ATHROW = (byte) 0xbf;
1612    protected static final byte MONITORENTER = (byte) 0xc2;
1613    protected static final byte MONITOREXIT = (byte) 0xc3;
1614    // ByteCode
1615
protected static final byte BIPUSH = (byte) 0x10;
1616    protected static final byte NEWARRAY = (byte) 0xbc;
1617    // ByteCode and FrameCode
1618
protected static final byte ILOAD = (byte) 0x15;
1619    protected static final byte LLOAD = (byte) 0x16;
1620    protected static final byte FLOAD = (byte) 0x17;
1621    protected static final byte DLOAD = (byte) 0x18;
1622    protected static final byte ALOAD = (byte) 0x19;
1623    protected static final byte ISTORE = (byte) 0x36;
1624    protected static final byte LSTORE = (byte) 0x37;
1625    protected static final byte FSTORE = (byte) 0x38;
1626    protected static final byte DSTORE = (byte) 0x39;
1627    protected static final byte ASTORE = (byte) 0x3a;
1628    protected static final byte RET = (byte) 0xa9;
1629    // ShortCode
1630
protected static final byte SIPUSH = (byte) 0x11;
1631    // PoolCode
1632
protected static final byte LDC = (byte) 0x12;
1633    protected static final byte LDC_W = (byte) 0x13;
1634    protected static final byte LDC2_W = (byte) 0x14;
1635    protected static final byte GETSTATIC = (byte) 0xb2;
1636    protected static final byte PUTSTATIC = (byte) 0xb3;
1637    protected static final byte GETFIELD = (byte) 0xb4;
1638    protected static final byte PUTFIELD = (byte) 0xb5;
1639    protected static final byte INVOKEVIRTUAL = (byte) 0xb6;
1640    protected static final byte INVOKESPECIAL = (byte) 0xb7;
1641    protected static final byte INVOKESTATIC = (byte) 0xb8;
1642    protected static final byte INVOKEINTERFACE = (byte) 0xb9;
1643    protected static final byte ANEWARRAY = (byte) 0xbd;
1644    protected static final byte NEW = (byte) 0xbb;
1645    protected static final byte CHECKCAST = (byte) 0xc0;
1646    protected static final byte INSTANCEOF = (byte) 0xc1;
1647    // BytePoolCode
1648
protected static final byte MULTIANEWARRAY = (byte) 0xc5;
1649    // BranchCode
1650
protected static final byte IFEQ = (byte) 0x99;
1651    protected static final byte IFNE = (byte) 0x9a;
1652    protected static final byte IFLT = (byte) 0x9b;
1653    protected static final byte IFGE = (byte) 0x9c;
1654    protected static final byte IFGT = (byte) 0x9d;
1655    protected static final byte IFLE = (byte) 0x9e;
1656    protected static final byte IF_ICMPEQ = (byte) 0x9f;
1657    protected static final byte IF_ICMPNE = (byte) 0xa0;
1658    protected static final byte IF_ICMPLT = (byte) 0xa1;
1659    protected static final byte IF_ICMPGE = (byte) 0xa2;
1660    protected static final byte IF_ICMPGT = (byte) 0xa3;
1661    protected static final byte IF_ICMPLE = (byte) 0xa4;
1662    protected static final byte IF_ACMPEQ = (byte) 0xa5;
1663    protected static final byte IF_ACMPNE = (byte) 0xa6;
1664    protected static final byte IFNULL = (byte) 0xc6;
1665    protected static final byte IFNONNULL = (byte) 0xc7;
1666    // JumpCode and JsrCode
1667
protected static final byte GOTO = (byte) 0xa7;
1668    protected static final byte JSR = (byte) 0xa8;
1669    protected static final byte GOTO_W = (byte) 0xc8;
1670    protected static final byte JSR_W = (byte) 0xc9;
1671    // SwitchCode
1672
protected static final byte TABLESWITCH = (byte) 0xaa;
1673    protected static final byte LOOKUPSWITCH = (byte) 0xab;
1674    // IncCode
1675
protected static final byte IINC = (byte) 0x84;
1676    // unused
1677
protected static final byte WIDE = (byte) 0xc4;
1678    protected static final byte XXXUNUSEDXXX1 = (byte) 0xba;
1679    protected static final byte BREAKPOINT = (byte) 0xca;
1680    protected static final byte IMPDEP1 = (byte) 0xfe;
1681    protected static final byte IMPDEP2 = (byte) 0xff;
1682
1683    // ------------------------------
1684
// debug
1685

1686    // if I cared about efficiency of printing I'd turn this into an
1687
// array, I suppose.
1688
private static String JavaDoc debugString(byte b) {
1689        switch (b) {
1690        case NOP: return "NOP";
1691        case ACONST_NULL: return "ACONST_NULL";
1692        case ICONST_M1: return "ICONST_M1";
1693        case ICONST_0: return "ICONST_0";
1694        case ICONST_1: return "ICONST_1";
1695        case ICONST_2: return "ICONST_2";
1696        case ICONST_3: return "ICONST_3";
1697        case ICONST_4: return "ICONST_4";
1698        case ICONST_5: return "ICONST_5";
1699        case LCONST_0: return "LCONST_0";
1700        case LCONST_1: return "LCONST_1";
1701        case FCONST_0: return "FCONST_0";
1702        case FCONST_1: return "FCONST_1";
1703        case FCONST_2: return "FCONST_2";
1704        case DCONST_0: return "DCONST_0";
1705        case DCONST_1: return "DCONST_1";
1706        case ILOAD_0: return "ILOAD_0";
1707        case ILOAD_1: return "ILOAD_1";
1708        case ILOAD_2: return "ILOAD_2";
1709        case ILOAD_3: return "ILOAD_3";
1710        case LLOAD_0: return "LLOAD_0";
1711        case LLOAD_1: return "LLOAD_1";
1712        case LLOAD_2: return "LLOAD_2";
1713        case LLOAD_3: return "LLOAD_3";
1714        case FLOAD_0: return "FLOAD_0";
1715        case FLOAD_1: return "FLOAD_1";
1716        case FLOAD_2: return "FLOAD_2";
1717        case FLOAD_3: return "FLOAD_3";
1718        case DLOAD_0: return "DLOAD_0";
1719        case DLOAD_1: return "DLOAD_1";
1720        case DLOAD_2: return "DLOAD_2";
1721        case DLOAD_3: return "DLOAD_3";
1722        case ALOAD_0: return "ALOAD_0";
1723        case ALOAD_1: return "ALOAD_1";
1724        case ALOAD_2: return "ALOAD_2";
1725        case ALOAD_3: return "ALOAD_3";
1726        case IALOAD: return "IALOAD";
1727        case LALOAD: return "LALOAD";
1728        case FALOAD: return "FALOAD";
1729        case DALOAD: return "DALOAD";
1730        case AALOAD: return "AALOAD";
1731        case BALOAD: return "BALOAD";
1732        case CALOAD: return "CALOAD";
1733        case SALOAD: return "SALOAD";
1734        case ISTORE_0: return "ISTORE_0";
1735        case ISTORE_1: return "ISTORE_1";
1736        case ISTORE_2: return "ISTORE_2";
1737        case ISTORE_3: return "ISTORE_3";
1738        case LSTORE_0: return "LSTORE_0";
1739        case LSTORE_1: return "LSTORE_1";
1740        case LSTORE_2: return "LSTORE_2";
1741        case LSTORE_3: return "LSTORE_3";
1742        case FSTORE_0: return "FSTORE_0";
1743        case FSTORE_1: return "FSTORE_1";
1744        case FSTORE_2: return "FSTORE_2";
1745        case FSTORE_3: return "FSTORE_3";
1746        case DSTORE_0: return "DSTORE_0";
1747        case DSTORE_1: return "DSTORE_1";
1748        case DSTORE_2: return "DSTORE_2";
1749        case DSTORE_3: return "DSTORE_3";
1750        case ASTORE_0: return "ASTORE_0";
1751        case ASTORE_1: return "ASTORE_1";
1752        case ASTORE_2: return "ASTORE_2";
1753        case ASTORE_3: return "ASTORE_3";
1754        case IASTORE: return "IASTORE";
1755        case LASTORE: return "LASTORE";
1756        case FASTORE: return "FASTORE";
1757        case DASTORE: return "DASTORE";
1758        case AASTORE: return "AASTORE";
1759        case BASTORE: return "BASTORE";
1760        case CASTORE: return "CASTORE";
1761        case SASTORE: return "SASTORE";
1762        case POP: return "POP";
1763        case POP2: return "POP2";
1764        case DUP: return "DUP";
1765        case DUP_X1: return "DUP_X1";
1766        case DUP_X2: return "DUP_X2";
1767        case DUP2: return "DUP2";
1768        case DUP2_X1: return "DUP2_X1";
1769        case DUP2_X2: return "DUP2_X2";
1770        case SWAP: return "SWAP";
1771        case IADD: return "IADD";
1772        case LADD: return "LADD";
1773        case FADD: return "FADD";
1774        case DADD: return "DADD";
1775        case ISUB: return "ISUB";
1776        case LSUB: return "LSUB";
1777        case FSUB: return "FSUB";
1778        case DSUB: return "DSUB";
1779        case IMUL: return "IMUL";
1780        case LMUL: return "LMUL";
1781        case FMUL: return "FMUL";
1782        case DMUL: return "DMUL";
1783        case IDIV: return "IDIV";
1784        case LDIV: return "LDIV";
1785        case FDIV: return "FDIV";
1786        case DDIV: return "DDIV";
1787        case IREM: return "IREM";
1788        case LREM: return "LREM";
1789        case FREM: return "FREM";
1790        case DREM: return "DREM";
1791        case INEG: return "INEG";
1792        case LNEG: return "LNEG";
1793        case FNEG: return "FNEG";
1794        case DNEG: return "DNEG";
1795        case ISHL: return "ISHL";
1796        case LSHL: return "LSHL";
1797        case ISHR: return "ISHR";
1798        case LSHR: return "LSHR";
1799        case IUSHR: return "IUSHR";
1800        case LUSHR: return "LUSHR";
1801        case IAND: return "IAND";
1802        case LAND: return "LAND";
1803        case IOR: return "IOR";
1804        case LOR: return "LOR";
1805        case IXOR: return "IXOR";
1806        case LXOR: return "LXOR";
1807        case I2L: return "I2L";
1808        case I2F: return "I2F";
1809        case I2D: return "I2D";
1810        case L2I: return "L2I";
1811        case L2F: return "L2F";
1812        case L2D: return "L2D";
1813        case F2I: return "F2I";
1814        case F2L: return "F2L";
1815        case F2D: return "F2D";
1816        case D2I: return "D2I";
1817        case D2L: return "D2L";
1818        case D2F: return "D2F";
1819        case I2B: return "I2B";
1820        case I2C: return "I2C";
1821        case I2S: return "I2S";
1822        case LCMP: return "LCMP";
1823        case FCMPL: return "FCMPL";
1824        case FCMPG: return "FCMPG";
1825        case DCMPL: return "DCMPL";
1826        case DCMPG: return "DCMPG";
1827        case IRETURN: return "IRETURN";
1828        case LRETURN: return "LRETURN";
1829        case FRETURN: return "FRETURN";
1830        case DRETURN: return "DRETURN";
1831        case ARETURN: return "ARETURN";
1832        case RETURN: return "RETURN";
1833        case ARRAYLENGTH: return "ARRAYLENGTH";
1834        case ATHROW: return "ATHROW";
1835        case MONITORENTER: return "MONITORENTER";
1836        case MONITOREXIT: return "MONITOREXIT";
1837        case BIPUSH: return "BIPUSH";
1838        case NEWARRAY: return "NEWARRAY";
1839        case ILOAD: return "ILOAD";
1840        case LLOAD: return "LLOAD";
1841        case FLOAD: return "FLOAD";
1842        case DLOAD: return "DLOAD";
1843        case ALOAD: return "ALOAD";
1844        case ISTORE: return "ISTORE";
1845        case LSTORE: return "LSTORE";
1846        case FSTORE: return "FSTORE";
1847        case DSTORE: return "DSTORE";
1848        case ASTORE: return "ASTORE";
1849        case RET: return "RET";
1850        case SIPUSH: return "SIPUSH";
1851        case LDC: return "LDC";
1852        case LDC_W: return "LDC_W";
1853        case LDC2_W: return "LDC2_W";
1854        case GETSTATIC: return "GETSTATIC";
1855        case PUTSTATIC: return "PUTSTATIC";
1856        case GETFIELD: return "GETFIELD";
1857        case PUTFIELD: return "PUTFIELD";
1858        case INVOKEVIRTUAL: return "INVOKEVIRTUAL";
1859        case INVOKESPECIAL: return "INVOKESPECIAL";
1860        case INVOKESTATIC: return "INVOKESTATIC";
1861        case INVOKEINTERFACE: return "INVOKEINTERFACE";
1862        case ANEWARRAY: return "ANEWARRAY";
1863        case NEW: return "NEW";
1864        case CHECKCAST: return "CHECKCAST";
1865        case INSTANCEOF: return "INSTANCEOF";
1866        case MULTIANEWARRAY: return "MULTIANEWARRAY";
1867        case IFEQ: return "IFEQ";
1868        case IFNE: return "IFNE";
1869        case IFLT: return "IFLT";
1870        case IFGE: return "IFGE";
1871        case IFGT: return "IFGT";
1872        case IFLE: return "IFLE";
1873        case IF_ICMPEQ: return "IF_ICMPEQ";
1874        case IF_ICMPNE: return "IF_ICMPNE";
1875        case IF_ICMPLT: return "IF_ICMPLT";
1876        case IF_ICMPGE: return "IF_ICMPGE";
1877        case IF_ICMPGT: return "IF_ICMPGT";
1878        case IF_ICMPLE: return "IF_ICMPLE";
1879        case IF_ACMPEQ: return "IF_ACMPEQ";
1880        case IF_ACMPNE: return "IF_ACMPNE";
1881        case IFNULL: return "IFNULL";
1882        case IFNONNULL: return "IFNONNULL";
1883        case GOTO: return "GOTO";
1884        case JSR: return "JSR";
1885        case GOTO_W: return "GOTO_W";
1886        case JSR_W: return "JSR_W";
1887        case TABLESWITCH: return "TABLESWITCH";
1888        case LOOKUPSWITCH: return "LOOKUPSWITCH";
1889        case IINC: return "IINC";
1890        case WIDE: return "WIDE";
1891        case XXXUNUSEDXXX1: return "XXXUNUSEDXXX1";
1892        case BREAKPOINT: return "BREAKPOINT";
1893        case IMPDEP1: return "IMPDEP1";
1894        case IMPDEP2: return "IMPDEP2";
1895        default: throw new RuntimeException JavaDoc("weird bytecode");
1896        }
1897    }
1898}
1899
Popular Tags