Source Code Cross Referenced for ClassFile.java in  » Scripting » Pnuts » pnuts » compiler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » Pnuts » pnuts.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * @(#)ClassFile.java 1.6 05/06/27
0003:         *
0004:         * Copyright (c) 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
0005:         *
0006:         * See the file "LICENSE.txt" for information on usage and redistribution
0007:         * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
0008:         */
0009:        package pnuts.compiler;
0010:
0011:        import java.io.DataOutputStream;
0012:        import java.io.IOException;
0013:        import java.io.OutputStream;
0014:        import java.util.Enumeration;
0015:        import java.util.ArrayList;
0016:        import java.util.List;
0017:
0018:        /**
0019:         * This class provides a way of making Java class file image.
0020:         */
0021:        public class ClassFile {
0022:
0023:            private final static long MAGIC = 0xcafebabe0003002dL;
0024:
0025:            private final static boolean DEBUG = false;
0026:
0027:            /**
0028:             *  The effect on the operand stack of a given opcode.
0029:             */
0030:            static final byte[] stackGrowth = { 0, // nop
0031:                    1, // aconst_null
0032:                    1, // iconst_m1
0033:                    1, // iconst_0
0034:                    1, // iconst_1
0035:                    1, // iconst_2
0036:                    1, // iconst_3
0037:                    1, // iconst_4
0038:                    1, // iconst_5
0039:                    2, // lconst_0
0040:                    2, // lconst_1
0041:                    1, // fconst_0
0042:                    1, // fconst_1
0043:                    1, // fconst_2
0044:                    2, // dconst_0
0045:                    2, // dconst_1
0046:                    1, // bipush
0047:                    1, // sipush
0048:                    1, // ldc
0049:                    1, // ldc_W
0050:                    2, // ldc2_W
0051:                    1, // iload
0052:                    2, // lload
0053:                    1, // fload
0054:                    2, // dload
0055:                    1, // aload
0056:                    1, // iload_0
0057:                    1, // iload_1
0058:                    1, // iload_2
0059:                    1, // iload_3
0060:                    2, // lload_0
0061:                    2, // lload_1
0062:                    2, // lload_2
0063:                    2, // lload_3
0064:                    1, // fload_0
0065:                    1, // fload_1
0066:                    1, // fload_2
0067:                    1, // fload_3
0068:                    2, // dload_0
0069:                    2, // dload_1
0070:                    2, // dload_2
0071:                    2, // dload_3
0072:                    1, // aload_0
0073:                    1, // aload_1
0074:                    1, // aload_2
0075:                    1, // aload_3
0076:                    -1, // iaload
0077:                    0, // laload
0078:                    -1, // faload
0079:                    0, // daload
0080:                    -1, // aaload
0081:                    -1, // baload
0082:                    -1, // caload
0083:                    -1, // saload
0084:                    -1, // istore
0085:                    -2, // lstore
0086:                    -1, // fstore
0087:                    -2, // dstore
0088:                    -1, // astore
0089:                    -1, // istore_0
0090:                    -1, // istore_1
0091:                    -1, // istore_2
0092:                    -1, // istore_3
0093:                    -2, // lstore_0
0094:                    -2, // lstore_1
0095:                    -2, // lstore_2
0096:                    -2, // lstore_3
0097:                    -1, // fstore_0
0098:                    -1, // fstore_1
0099:                    -1, // fstore_2
0100:                    -1, // fstore_3
0101:                    -2, // dstore_0
0102:                    -2, // dstore_1
0103:                    -2, // dstore_2
0104:                    -2, // dstore_3
0105:                    -1, // astore_0
0106:                    -1, // astore_1
0107:                    -1, // astore_2
0108:                    -1, // astore_3
0109:                    -3, // iastore
0110:                    -4, // lastore
0111:                    -3, // fastore
0112:                    -4, // dastore
0113:                    -3, // aastore
0114:                    -3, // bastore
0115:                    -3, // castore
0116:                    -3, // sastore
0117:                    -1, // pop
0118:                    -2, // pop2
0119:                    1, // dup
0120:                    1, // dup_X1
0121:                    1, // dup_X2
0122:                    2, // dup2
0123:                    2, // dup2_X1
0124:                    2, // dup2_X2
0125:                    0, // swap
0126:                    -1, // iadd
0127:                    -2, // ladd
0128:                    -1, // fadd
0129:                    -2, // dadd
0130:                    -1, // isub
0131:                    -2, // lsub
0132:                    -1, // fsub
0133:                    -2, // dsub
0134:                    -1, // imul
0135:                    -2, // lmul
0136:                    -1, // fmul
0137:                    -2, // dmul
0138:                    -1, // idiv
0139:                    -2, // ldiv
0140:                    -1, // fdiv
0141:                    -2, // ddiv
0142:                    -1, // irem
0143:                    -2, // lrem
0144:                    -1, // frem
0145:                    -2, // drem
0146:                    0, // ineg
0147:                    0, // lneg
0148:                    0, // fneg
0149:                    0, // dneg
0150:                    -1, // ishl
0151:                    -1, // lshl
0152:                    -1, // ishr
0153:                    -1, // lshr
0154:                    -1, // iushr
0155:                    -1, // lushr
0156:                    -1, // iand
0157:                    -2, // land
0158:                    -1, // ior
0159:                    -2, // lor
0160:                    -1, // ixor
0161:                    -2, // lxor
0162:                    0, // iinc
0163:                    1, // i2l
0164:                    0, // i2f
0165:                    1, // i2d
0166:                    -1, // l2i
0167:                    -1, // l2f
0168:                    0, // l2d
0169:                    0, // f2i
0170:                    1, // f2l
0171:                    1, // f2d
0172:                    -1, // d2i
0173:                    0, // d2l
0174:                    -1, // d2f
0175:                    0, // i2b
0176:                    0, // i2c
0177:                    0, // i2s
0178:                    -3, // lcmp
0179:                    -1, // fcmpl
0180:                    -1, // fcmpg
0181:                    -3, // dcmpl
0182:                    -3, // dcmpg
0183:                    -1, // ifeq
0184:                    -1, // ifne
0185:                    -1, // iflt
0186:                    -1, // ifge
0187:                    -1, // ifgt
0188:                    -1, // ifle
0189:                    -2, // if_icmpeq
0190:                    -2, // if_icmpne
0191:                    -2, // if_icmplt
0192:                    -2, // if_icmpge
0193:                    -2, // if_icmpgt
0194:                    -2, // if_icmple
0195:                    -2, // if_acmpeq
0196:                    -2, // if_acmpne
0197:                    0, // goto
0198:                    0, // jsr
0199:                    0, // ret
0200:                    -1, // tableswitch
0201:                    -1, // lookupswitch
0202:                    -1, // ireturn
0203:                    -2, // lreturn
0204:                    -1, // freturn
0205:                    -2, // dreturn
0206:                    -1, // areturn
0207:                    0, // return
0208:                    0, // getstatic
0209:                    0, // putstatic
0210:                    -1, // getfield
0211:                    -1, // putfield
0212:                    -1, // invokevirtual
0213:                    -1, // invokespecial
0214:                    0, // invokestatic
0215:                    -1, // invokeinterface
0216:                    0, // UNUSED
0217:                    1, // new
0218:                    0, // newarray
0219:                    0, // anewarray
0220:                    0, // arraylength
0221:                    -1, // athrow
0222:                    0, // checkcast
0223:                    0, // instanceof
0224:                    -1, // monitorenter
0225:                    -1, // monitorexit
0226:                    0, // wide
0227:                    1, // multianewarray
0228:                    -1, // ifnull
0229:                    -1, // ifnonnull
0230:                    0, // goto_w
0231:                    1, // jsr_w
0232:                    0, // breakpoint
0233:                    1, // ldc_quick
0234:                    1, // ldc_w_quick
0235:                    2, // ldc2_w_quick
0236:                    0, // getfield_quick
0237:                    0, // putfield_quick
0238:                    0, // getfield2_quick
0239:                    0, // putfield2_quick
0240:                    0, // getstatic_quick
0241:                    0, // putstatic_quick
0242:                    0, // getstatic2_quick
0243:                    0, // putstatic2_quick
0244:                    0, // invokevirtual_quick
0245:                    0, // invokenonvirtual_quick
0246:                    0, // invokesuper_quick
0247:                    0, // invokestatic_quick
0248:                    0, // invokeinterface_quick
0249:                    0, // invokevirtualobject_quick
0250:                    0, // UNUSED
0251:                    1, // new_quick
0252:                    1, // anewarray_quick
0253:                    1, // multianewarray_quick
0254:                    -1, // checkcast_quick
0255:                    0, // instanceof_quick
0256:                    0, // invokevirtual_quick_w
0257:                    0, // getfield_quick_w
0258:                    0 // putfield_quick_w
0259:            };
0260:
0261:            private ConstantPool constantPool;
0262:
0263:            private List methods = new ArrayList(); // MethodInfo
0264:
0265:            private MethodInfo currentMethod;
0266:
0267:            private List fields = new ArrayList(); // FieldInfo
0268:
0269:            private List exceptionTable;
0270:
0271:            private List interfaces = new ArrayList();
0272:
0273:            private short this ClassIndex;
0274:
0275:            private short super ClassIndex;
0276:
0277:            private short sourceFileNameIndex;
0278:
0279:            private short accessFlags;
0280:
0281:            private short maxStack;
0282:
0283:            private short stackTop;
0284:
0285:            private boolean locals[];
0286:
0287:            public ClassFile parent;
0288:
0289:            private String className;
0290:
0291:            private int maxLocal;
0292:
0293:            ByteBuffer codeBuffer;
0294:
0295:            public ClassFile(String this Class, String super Class,
0296:                    String sourceFile, short accessFlags) {
0297:
0298:                constantPool = new ConstantPool();
0299:                this ClassIndex = constantPool.addClass(this Class);
0300:                super ClassIndex = constantPool.addClass(super Class);
0301:                if (sourceFile != null) {
0302:                    sourceFileNameIndex = constantPool.addUTF8(sourceFile);
0303:                }
0304:                this .accessFlags = accessFlags;
0305:                this .className = this Class;
0306:            }
0307:
0308:            public String getClassName() {
0309:                return className;
0310:            }
0311:
0312:            public void setCodeBuffer(ByteBuffer cbuf) {
0313:                this .codeBuffer = cbuf;
0314:            }
0315:
0316:            public ByteBuffer getCodeBuffer() {
0317:                return codeBuffer;
0318:            }
0319:
0320:            public int codeSize() {
0321:                return codeBuffer.size();
0322:            }
0323:
0324:            public void addInterface(String interfaceName) {
0325:                interfaces.add(new Short(constantPool.addClass(interfaceName)));
0326:            }
0327:
0328:            public void addField(String fieldName, String type,
0329:                    short accessFlags) {
0330:                fields.add(new FieldInfo(constantPool.addUTF8(fieldName),
0331:                        constantPool.addUTF8(type), accessFlags));
0332:            }
0333:
0334:            public short addConstant(String value) {
0335:                return constantPool.addConstant(value);
0336:            }
0337:
0338:            public void addConstant(String fieldName, String type, short flags,
0339:                    short valueIndex) {
0340:                short fieldNameIndex = constantPool.addUTF8(fieldName);
0341:                short typeIndex = constantPool.addUTF8(type);
0342:                short cvAttr[] = new short[4];
0343:                cvAttr[0] = constantPool.addUTF8("ConstantValue");
0344:                cvAttr[1] = 0;
0345:                cvAttr[2] = 2;
0346:                cvAttr[3] = valueIndex;
0347:                fields.add(new FieldInfo(fieldNameIndex, typeIndex, flags,
0348:                        cvAttr));
0349:            }
0350:
0351:            public void addConstant(String fieldName, String type, short flags,
0352:                    int value) {
0353:                addConstant(fieldName, type, flags, constantPool
0354:                        .addConstant(value));
0355:            }
0356:
0357:            public void addConstant(String fieldName, String type, short flags,
0358:                    long value) {
0359:                addConstant(fieldName, type, flags, constantPool
0360:                        .addConstant(value));
0361:            }
0362:
0363:            public void addConstant(String fieldName, String type, short flags,
0364:                    double value) {
0365:                addConstant(fieldName, type, flags, constantPool
0366:                        .addConstant(value));
0367:            }
0368:
0369:            public void addConstant(String fieldName, String type, short flags,
0370:                    String value) {
0371:                addConstant(fieldName, type, flags, constantPool
0372:                        .addConstant(value));
0373:            }
0374:
0375:            public void openMethod(String methodName, String type, short flag) {
0376:                openMethod(methodName, type, flag, null);
0377:            }
0378:
0379:            public void openMethod(String methodName, String type, short flag,
0380:                    String[] exceptions) {
0381:                codeBuffer = new ByteBuffer();
0382:                int sig = sizeOfParameters(type);
0383:                int nlocals = sig & 0xff;
0384:                if ((flag & Constants.ACC_STATIC) != Constants.ACC_STATIC) {
0385:                    nlocals++;
0386:                }
0387:
0388:                locals = new boolean[nlocals + 32];
0389:                for (int i = 0; i < nlocals; i++) {
0390:                    this .locals[i] = true;
0391:                }
0392:                maxLocal = nlocals;
0393:
0394:                ExceptionAttr exceptionAttr = null;
0395:                if (exceptions != null) {
0396:                    short exceptionAttributeIndex = constantPool
0397:                            .addUTF8("Exceptions");
0398:                    short[] e = new short[exceptions.length];
0399:                    for (int i = 0; i < exceptions.length; i++) {
0400:                        e[i] = constantPool.addClass(exceptions[i]);
0401:                    }
0402:                    exceptionAttr = new ExceptionAttr(exceptionAttributeIndex,
0403:                            e);
0404:                }
0405:                currentMethod = new MethodInfo(
0406:                        constantPool.addUTF8(methodName), constantPool
0407:                                .addUTF8(type), flag, exceptionAttr);
0408:                methods.add(currentMethod);
0409:            }
0410:
0411:            public void closeMethod() {
0412:                if ((currentMethod.accessFlags & Constants.ACC_ABSTRACT) == Constants.ACC_ABSTRACT) {
0413:                    return;
0414:                }
0415:                int codeSize = codeSize();
0416:                if (DEBUG) {
0417:                    System.out.println("codeSize = " + codeSize);
0418:                }
0419:                if (codeSize > 65535) {
0420:                    throw new ClassFormatError("code size is too large "
0421:                            + codeSize);
0422:                }
0423:                int exceptionSize = 0;
0424:                if (exceptionTable != null) {
0425:                    exceptionSize = exceptionTable.size();
0426:                }
0427:                LineNumberTable lineNumberTable = currentMethod.lineNumberTable;
0428:                int lineNumberSize = 0;
0429:                if (lineNumberTable != null) {
0430:                    lineNumberSize = 8 + 4 * lineNumberTable.size();
0431:                }
0432:
0433:                int attrLength = 2 + // attribute_name_index
0434:                        4 + // attribute_length
0435:                        2 + // max_stack
0436:                        2 + // max_locals
0437:                        4 + // code_length
0438:                        codeSize + 2 + // exception_table_length
0439:                        (exceptionSize * 8) + 2 + // attributes_count
0440:                        lineNumberSize; // LineNumberTable
0441:
0442:                ByteBuffer codeAttr = new ByteBuffer(attrLength);
0443:                int codeAttrIndex = constantPool.addUTF8("Code");
0444:                codeAttr.add((short) codeAttrIndex);
0445:
0446:                int attr_len = attrLength - 6;
0447:                codeAttr.add(attr_len);
0448:                codeAttr.add((short) maxStack);
0449:                codeAttr.add((short) maxLocal);
0450:
0451:                codeAttr.add(codeSize);
0452:                codeAttr.append(codeBuffer);
0453:
0454:                if (exceptionSize > 0) {
0455:                    codeAttr.add((short) exceptionTable.size());
0456:                    for (int i = 0, n = exceptionTable.size(); i < n; i++) {
0457:                        ExceptionTableEntry entry = (ExceptionTableEntry) exceptionTable
0458:                                .get(i);
0459:                        codeAttr.add(entry.start.getPC());
0460:                        codeAttr.add(entry.end.getPC());
0461:                        codeAttr.add(entry.handler.getPC());
0462:                        codeAttr.add(entry.catchType);
0463:                    }
0464:                    /*
0465:                    for (Enumeration e = exceptionTable.elements(); e.hasMoreElements();) {
0466:                    	ExceptionTableEntry entry = (ExceptionTableEntry) e
0467:                    			.nextElement();
0468:                    	codeAttr.add(entry.start.getPC());
0469:                    	codeAttr.add(entry.end.getPC());
0470:                    	codeAttr.add(entry.handler.getPC());
0471:                    	codeAttr.add(entry.catchType);
0472:                    }
0473:                     */
0474:                } else {
0475:                    codeAttr.add((short) 0);
0476:                }
0477:
0478:                if (lineNumberTable != null) {
0479:                    codeAttr.add((short) 1);
0480:                } else {
0481:                    codeAttr.add((short) 0);
0482:                }
0483:
0484:                currentMethod.setCodeAttribute(codeAttr);
0485:
0486:                exceptionTable = null;
0487:                codeBuffer.setSize(0);
0488:                currentMethod = null;
0489:                maxStack = 0;
0490:                maxLocal = 0;
0491:                stackTop = 0;
0492:            }
0493:
0494:            public void shift(int offset) {
0495:                if (exceptionTable != null) {
0496:                    for (int i = 0, n = exceptionTable.size(); i < n; i++) {
0497:                        ExceptionTableEntry entry = (ExceptionTableEntry) exceptionTable
0498:                                .get(i);
0499:                        entry.start = entry.start.shift(offset);
0500:                        entry.end = entry.end.shift(offset);
0501:                        entry.handler = entry.handler.shift(offset);
0502:                    }
0503:                }
0504:                LineNumberTable lineNumberTable = this .currentMethod.lineNumberTable;
0505:                if (lineNumberTable != null) {
0506:                    lineNumberTable.shift(offset);
0507:                }
0508:            }
0509:
0510:            void updateStack(byte opcode) {
0511:                int idx = opcode & 0xff;
0512:                int growth = stackGrowth[idx];
0513:                stackTop += growth;
0514:                if (stackTop > maxStack) {
0515:                    maxStack = stackTop;
0516:                }
0517:            }
0518:
0519:            public void popStack() {
0520:                --stackTop;
0521:            }
0522:
0523:            public void add(byte opcode) {
0524:                codeBuffer.add(opcode);
0525:                updateStack(opcode);
0526:            }
0527:
0528:            public void addByte(byte val) {
0529:                codeBuffer.add(val);
0530:            }
0531:
0532:            public void addInt(int ival) {
0533:                codeBuffer.add((byte) ((ival >> 24) & 0xff));
0534:                codeBuffer.add((byte) ((ival >> 16) & 0xff));
0535:                codeBuffer.add((byte) ((ival >> 8) & 0xff));
0536:                codeBuffer.add((byte) ((ival >> 0) & 0xff));
0537:            }
0538:
0539:            public Label getLabel() {
0540:                return getLabel(false);
0541:            }
0542:
0543:            public Label getLabel(boolean fixed) {
0544:                Label label = new Label(this );
0545:                if (fixed) {
0546:                    label.fix();
0547:                }
0548:                return label;
0549:            }
0550:
0551:            public int declareLocal() {
0552:                if (maxLocal >= locals.length) {
0553:                    boolean[] new_locals = new boolean[locals.length * 2];
0554:                    System.arraycopy(locals, 0, new_locals, 0, locals.length);
0555:                    locals = new_locals;
0556:                }
0557:                locals[maxLocal] = true;
0558:                return maxLocal++;
0559:            }
0560:
0561:            public int getLocal() {
0562:                for (int i = 0; i < maxLocal; i++) {
0563:                    if (!locals[i]) {
0564:                        locals[i] = true;
0565:                        return i;
0566:                    }
0567:                }
0568:                if (maxLocal >= locals.length) {
0569:                    boolean[] new_locals = new boolean[locals.length * 2];
0570:                    System.arraycopy(locals, 0, new_locals, 0, locals.length);
0571:                    locals = new_locals;
0572:                }
0573:                locals[maxLocal] = true;
0574:                return maxLocal++;
0575:            }
0576:
0577:            public void freeLocal(int index) {
0578:                locals[index] = false;
0579:            }
0580:
0581:            public void istoreLocal(int index) {
0582:                if (index >= 0 && index < 4) {
0583:                    add((byte) (Opcode.ISTORE_0 + index));
0584:                } else {
0585:                    add(Opcode.ISTORE, index);
0586:                }
0587:            }
0588:
0589:            public void iloadLocal(int index) {
0590:                if (index >= 0 && index < 4) {
0591:                    add((byte) (Opcode.ILOAD_0 + index));
0592:                } else {
0593:                    add(Opcode.ILOAD, index);
0594:                }
0595:            }
0596:
0597:            public void lloadLocal(int index) {
0598:                if (index >= 0 && index < 4) {
0599:                    add((byte) (Opcode.LLOAD_0 + index));
0600:                } else {
0601:                    add(Opcode.LLOAD, index);
0602:                }
0603:            }
0604:
0605:            public void floadLocal(int index) {
0606:                if (index >= 0 && index < 4) {
0607:                    add((byte) (Opcode.FLOAD_0 + index));
0608:                } else {
0609:                    add(Opcode.FLOAD, index);
0610:                }
0611:            }
0612:
0613:            public void dloadLocal(int index) {
0614:                if (index >= 0 && index < 4) {
0615:                    add((byte) (Opcode.DLOAD_0 + index));
0616:                } else {
0617:                    add(Opcode.DLOAD, index);
0618:                }
0619:            }
0620:
0621:            public void loadLocal(int index) {
0622:                if (index >= 0 && index < 4) {
0623:                    add((byte) (Opcode.ALOAD_0 + index));
0624:                } else {
0625:                    add(Opcode.ALOAD, index);
0626:                }
0627:            }
0628:
0629:            public void storeLocal(int index) {
0630:                if (index >= 0 && index < 4) {
0631:                    add((byte) (Opcode.ASTORE_0 + index));
0632:                } else {
0633:                    add(Opcode.ASTORE, index);
0634:                }
0635:            }
0636:
0637:            public void add(byte opcode, Label label) {
0638:                switch (opcode) {
0639:                case Opcode.GOTO: // fall-through
0640:                case Opcode.IFEQ:
0641:                case Opcode.IFNE:
0642:                case Opcode.IFLT:
0643:                case Opcode.IFGE:
0644:                case Opcode.IFGT:
0645:                case Opcode.IFLE:
0646:                case Opcode.IF_ICMPEQ:
0647:                case Opcode.IF_ICMPNE:
0648:                case Opcode.IF_ICMPLT:
0649:                case Opcode.IF_ICMPGE:
0650:                case Opcode.IF_ICMPGT:
0651:                case Opcode.IF_ICMPLE:
0652:                case Opcode.IF_ACMPEQ:
0653:                case Opcode.IF_ACMPNE:
0654:                case Opcode.JSR:
0655:                case Opcode.IFNULL:
0656:                case Opcode.IFNONNULL:
0657:                    int pc = codeBuffer.size();
0658:                    codeBuffer.add(opcode);
0659:                    label.register(pc, 2);
0660:                    int growth = stackGrowth[opcode & 0xff];
0661:                    stackTop += growth;
0662:                    break;
0663:                }
0664:            }
0665:
0666:            public void pushInteger(int number) {
0667:                if (number >= -1 && number <= 5) {
0668:                    add((byte) (Opcode.ICONST_0 + number));
0669:                } else if (number > -0x80 && number < 0x80) {
0670:                    add(Opcode.BIPUSH, number);
0671:                } else if (number > -0x8000 && number < 0x8000) {
0672:                    add(Opcode.SIPUSH, number);
0673:                } else {
0674:                    add(Opcode.LDC, constantPool.addConstant(number));
0675:                }
0676:            }
0677:
0678:            public void pushLong(long number) {
0679:                if (number == 0) {
0680:                    add(Opcode.LCONST_0);
0681:                } else if (number == 1) {
0682:                    add(Opcode.LCONST_1);
0683:                } else {
0684:                    add(Opcode.LDC2_W, constantPool.addConstant(number));
0685:                }
0686:            }
0687:
0688:            public void pushFloat(float number) {
0689:                if (number == 0.0f) {
0690:                    add(Opcode.FCONST_0);
0691:                } else if (number == 1.0f) {
0692:                    add(Opcode.FCONST_1);
0693:                } else if (number == 2.0f) {
0694:                    add(Opcode.FCONST_2);
0695:                } else {
0696:                    add(Opcode.LDC_W, constantPool.addConstant(number));
0697:                }
0698:            }
0699:
0700:            public void pushDouble(double number) {
0701:                if (number == 0) {
0702:                    add(Opcode.DCONST_0);
0703:                } else if (number == 1) {
0704:                    add(Opcode.DCONST_1);
0705:                } else {
0706:                    add(Opcode.LDC2_W, constantPool.addConstant(number));
0707:                }
0708:            }
0709:
0710:            public void pushString(String str) {
0711:                int len = str.length();
0712:                if (len > 32767 / 3) {
0713:                    pushLargeString(str);
0714:                } else {
0715:                    add(Opcode.LDC, addConstant(str));
0716:                }
0717:            }
0718:
0719:            void pushLargeString(String str) {
0720:                add(Opcode.NEW, "java.lang.StringBuffer");
0721:                add(Opcode.DUP);
0722:                add(Opcode.INVOKESPECIAL, "java.lang.StringBuffer", "<init>",
0723:                        "()", "V");
0724:                int x = 32767 / 3;
0725:                int len = str.length();
0726:                int n = len / x;
0727:                int m = len % x;
0728:                for (int i = 0; i < n; i++) {
0729:                    add(Opcode.LDC, addConstant(str.substring(i * x, (i + 1)
0730:                            * x)));
0731:                    add(Opcode.INVOKEVIRTUAL, "java.lang.StringBuffer",
0732:                            "append", "(Ljava/lang/String;)",
0733:                            "Ljava/lang/StringBuffer;");
0734:                }
0735:                if (m > 0) {
0736:                    add(Opcode.LDC, addConstant(str.substring(n * x)));
0737:                    add(Opcode.INVOKEVIRTUAL, "java.lang.StringBuffer",
0738:                            "append", "(Ljava/lang/String;)",
0739:                            "Ljava/lang/StringBuffer;");
0740:                }
0741:                add(Opcode.INVOKEVIRTUAL, "java.lang.StringBuffer", "toString",
0742:                        "()", "Ljava/lang/String;");
0743:            }
0744:
0745:            public void add(byte opcode, int operand) {
0746:                updateStack(opcode);
0747:                switch (opcode) {
0748:                case Opcode.BIPUSH:
0749:                    codeBuffer.add(opcode);
0750:                    codeBuffer.add((byte) operand);
0751:                    break;
0752:                case Opcode.SIPUSH:
0753:                    codeBuffer.add(opcode);
0754:                    codeBuffer.add((short) operand);
0755:                    break;
0756:                case Opcode.NEWARRAY:
0757:                    codeBuffer.add(opcode);
0758:                    codeBuffer.add((byte) operand);
0759:                    break;
0760:                case Opcode.GETFIELD:
0761:                case Opcode.PUTFIELD:
0762:                    codeBuffer.add(opcode);
0763:                    codeBuffer.add(operand);
0764:                    break;
0765:                case Opcode.LDC:
0766:                case Opcode.LDC_W:
0767:                case Opcode.LDC2_W:
0768:                    if ((operand >= 256) || (opcode == Opcode.LDC_W)
0769:                            || (opcode == Opcode.LDC2_W)) {
0770:
0771:                        if (opcode == Opcode.LDC) {
0772:                            codeBuffer.add(Opcode.LDC_W);
0773:                        } else {
0774:                            codeBuffer.add(opcode);
0775:                        }
0776:                        codeBuffer.add((short) operand);
0777:                    } else {
0778:                        codeBuffer.add(opcode);
0779:                        codeBuffer.add((byte) operand);
0780:                    }
0781:                    break;
0782:                case Opcode.RET:
0783:                case Opcode.ILOAD:
0784:                case Opcode.LLOAD:
0785:                case Opcode.FLOAD:
0786:                case Opcode.DLOAD:
0787:                case Opcode.ALOAD:
0788:                case Opcode.ISTORE:
0789:                case Opcode.LSTORE:
0790:                case Opcode.FSTORE:
0791:                case Opcode.DSTORE:
0792:                case Opcode.ASTORE:
0793:                    if (operand >= 256) {
0794:                        codeBuffer.add(Opcode.WIDE);
0795:                        codeBuffer.add(opcode);
0796:                        codeBuffer.add((short) operand);
0797:                    } else {
0798:                        codeBuffer.add(opcode);
0799:                        codeBuffer.add((byte) operand);
0800:                    }
0801:                    break;
0802:                default:
0803:                    throw new ClassFileException(
0804:                            "Unexpected opcode for 1 operand");
0805:                }
0806:            }
0807:
0808:            public void add(byte opcode, int operand1, int operand2) {
0809:                updateStack(opcode);
0810:                if (opcode == Opcode.IINC) {
0811:                    if ((operand1 > 255) || (operand2 < -128)
0812:                            || (operand2 > 127)) {
0813:                        codeBuffer.add(Opcode.WIDE);
0814:                        codeBuffer.add(Opcode.IINC);
0815:                        codeBuffer.add((short) operand1);
0816:                        codeBuffer.add((short) operand2);
0817:                    } else {
0818:                        codeBuffer.add(Opcode.IINC);
0819:                        codeBuffer.add((byte) operand1);
0820:                        codeBuffer.add((byte) operand2);
0821:                    }
0822:                } else {
0823:                    if (opcode == Opcode.MULTIANEWARRAY) {
0824:                        codeBuffer.add(Opcode.MULTIANEWARRAY);
0825:                        codeBuffer.add((short) operand1);
0826:                        codeBuffer.add((byte) operand2);
0827:                    } else {
0828:                        throw new ClassFileException(
0829:                                "Unexpected opcode for 2 operands");
0830:                    }
0831:                }
0832:            }
0833:
0834:            public void add(byte opcode, String className) {
0835:                updateStack(opcode);
0836:                switch (opcode) {
0837:                case Opcode.NEW:
0838:                case Opcode.ANEWARRAY:
0839:                case Opcode.CHECKCAST:
0840:                case Opcode.INSTANCEOF:
0841:                    short classIndex = constantPool.addClass(className);
0842:                    codeBuffer.add(opcode);
0843:                    codeBuffer.add(classIndex);
0844:                    break;
0845:                default:
0846:                    throw new ClassFileException(
0847:                            "bad opcode for class reference:" + opcode);
0848:                }
0849:            }
0850:
0851:            public void add(byte opcode, String className, String fieldName,
0852:                    String fieldType) {
0853:                int growth = stackGrowth[opcode & 0xFF];
0854:                stackTop += growth;
0855:
0856:                char fieldTypeChar = fieldType.charAt(0);
0857:                int fieldSize = ((fieldTypeChar == 'J') || (fieldTypeChar == 'D')) ? 2
0858:                        : 1;
0859:
0860:                switch (opcode) {
0861:                case Opcode.GETFIELD:
0862:                case Opcode.GETSTATIC:
0863:                    stackTop += fieldSize;
0864:                    break;
0865:                case Opcode.PUTSTATIC:
0866:                case Opcode.PUTFIELD:
0867:                    stackTop -= fieldSize;
0868:                    break;
0869:                default:
0870:                    throw new ClassFileException(
0871:                            "bad opcode for field reference:" + opcode);
0872:                }
0873:                short fieldRefIndex = constantPool.addFieldRef(className,
0874:                        fieldName, fieldType);
0875:                codeBuffer.add(opcode);
0876:                codeBuffer.add(fieldRefIndex);
0877:
0878:                if (stackTop > maxStack) {
0879:                    maxStack = stackTop;
0880:                }
0881:            }
0882:
0883:            public void add(byte opcode, String className, String methodName,
0884:                    String parametersType, String returnType) {
0885:                int info = sizeOfParameters(parametersType);
0886:                int arg_size = info & 0xffff;
0887:
0888:                int growth = stackGrowth[opcode & 0xFF] - arg_size;
0889:                stackTop += growth;
0890:                /*
0891:                 * if (stackTop > maxStack){ maxStack = stackTop; }
0892:                 */
0893:                switch (opcode) {
0894:                case Opcode.INVOKEVIRTUAL:
0895:                case Opcode.INVOKESPECIAL:
0896:                case Opcode.INVOKESTATIC:
0897:                case Opcode.INVOKEINTERFACE:
0898:                    stackTop += sizeOfReturn(returnType);
0899:                    codeBuffer.add(opcode);
0900:                    if (opcode == Opcode.INVOKEINTERFACE) {
0901:                        short ifMethodRefIndex = constantPool
0902:                                .addInterfaceMethodRef(className, methodName,
0903:                                        parametersType + returnType);
0904:                        codeBuffer.add(ifMethodRefIndex);
0905:                        codeBuffer.add((byte) (arg_size + 1));
0906:                        codeBuffer.add((byte) 0);
0907:                    } else {
0908:                        short methodRefIndex = constantPool.addMethodRef(
0909:                                className, methodName, parametersType
0910:                                        + returnType);
0911:                        codeBuffer.add(methodRefIndex);
0912:                    }
0913:                    break;
0914:                default:
0915:                    throw new ClassFileException(
0916:                            "bad opcode for method reference:" + opcode);
0917:                }
0918:
0919:                if (stackTop > maxStack) {
0920:                    maxStack = stackTop;
0921:                }
0922:            }
0923:
0924:            public void reserveStack(int size) {
0925:                stackTop += size;
0926:                if (stackTop > maxStack) {
0927:                    maxStack = stackTop;
0928:                }
0929:            }
0930:
0931:            public static final int sizeOfReturn(String sig) {
0932:                int size = 0;
0933:                char c = sig.charAt(0);
0934:                if (c != 'V') {
0935:                    if ((c == 'J') || (c == 'D')) {
0936:                        size += 2;
0937:                    } else {
0938:                        size++;
0939:                    }
0940:                }
0941:                return size;
0942:            }
0943:
0944:            public static final int sizeOfParameters(String sig) {
0945:                return sizeOfParameters(sig.toCharArray(), 1);
0946:            }
0947:
0948:            static int sizeOfParameters(char c[], int offset) {
0949:                int index = offset;
0950:                int size = 0;
0951:                int narg = 0;
0952:                loop: while (index < c.length) {
0953:                    switch (c[index]) {
0954:                    case 'J':
0955:                    case 'D':
0956:                        size += 2;
0957:                        index++;
0958:                        narg++;
0959:                        break;
0960:                    case 'B':
0961:                    case 'S':
0962:                    case 'C':
0963:                    case 'I':
0964:                    case 'Z':
0965:                    case 'F':
0966:                        size++;
0967:                        index++;
0968:                        narg++;
0969:                        break;
0970:                    case '[':
0971:                        while (c[index] == '[') {
0972:                            index++;
0973:                        }
0974:                        if (c[index] != 'L') {
0975:                            size++;
0976:                            index++;
0977:                            narg++;
0978:                            break;
0979:                        } // fall through
0980:                    case 'L':
0981:                        size++;
0982:                        narg++;
0983:                        while (c[index++] != ';') {
0984:                        }
0985:                        break;
0986:                    case ')':
0987:                        break loop;
0988:                    default:
0989:                        throw new ClassFileException("Bad signature character:"
0990:                                + c[index]);
0991:                    }
0992:                }
0993:                return (narg << 16) | size;
0994:            }
0995:
0996:            public void addExceptionHandler(Label startLabel, Label endLabel,
0997:                    Label handlerLabel, String catchClassName) {
0998:                short catch_type;
0999:                if (catchClassName != null) {
1000:                    catch_type = constantPool.addClass(catchClassName);
1001:                } else {
1002:                    catch_type = 0;
1003:                }
1004:                ExceptionTableEntry newEntry = new ExceptionTableEntry(
1005:                        startLabel, endLabel, handlerLabel, catch_type);
1006:
1007:                if (exceptionTable == null) {
1008:                    exceptionTable = new ArrayList();
1009:                }
1010:                exceptionTable.add(newEntry);
1011:            }
1012:
1013:            public void write(OutputStream stream) throws IOException {
1014:                DataOutputStream out;
1015:                if (stream instanceof  DataOutputStream) {
1016:                    out = (DataOutputStream) stream;
1017:                } else {
1018:                    out = new DataOutputStream(stream);
1019:                }
1020:                short sourceFileIndex = 0;
1021:                if (sourceFileNameIndex != 0) {
1022:                    sourceFileIndex = constantPool.addUTF8("SourceFile");
1023:                }
1024:                out.writeLong(MAGIC);
1025:                constantPool.write(out);
1026:                out.writeShort(this .accessFlags);
1027:                out.writeShort(this ClassIndex);
1028:                out.writeShort(super ClassIndex);
1029:                out.writeShort(interfaces.size());
1030:                for (int i = 0; i < interfaces.size(); i++) {
1031:                    out.writeShort(((Short) interfaces.get(i)).shortValue());
1032:                }
1033:                out.writeShort(fields.size());
1034:                for (int i = 0; i < fields.size(); i++) {
1035:                    ((FieldInfo) fields.get(i)).write(out);
1036:                }
1037:                out.writeShort(methods.size());
1038:                for (int i = 0; i < methods.size(); i++) {
1039:                    ((MethodInfo) methods.get(i)).write(out);
1040:                }
1041:                if (sourceFileNameIndex != 0) {
1042:                    out.writeShort(1); // attributes count
1043:                    out.writeShort(sourceFileIndex);
1044:                    out.writeInt(2);
1045:                    out.writeShort(sourceFileNameIndex);
1046:                } else {
1047:                    out.writeShort(0); // no attributes
1048:                }
1049:            }
1050:
1051:            public static String signature(Class[] paramTypes) {
1052:                StringBuffer buf = new StringBuffer();
1053:                buf.append('(');
1054:                for (int i = 0; i < paramTypes.length; i++) {
1055:                    buf.append(signature(paramTypes[i]));
1056:                }
1057:                buf.append(')');
1058:                return buf.toString();
1059:            }
1060:
1061:            public static String signature(Class clazz) {
1062:                if (clazz == int.class) {
1063:                    return "I";
1064:                } else if (clazz == short.class) {
1065:                    return "S";
1066:                } else if (clazz == byte.class) {
1067:                    return "B";
1068:                } else if (clazz == char.class) {
1069:                    return "C";
1070:                } else if (clazz == long.class) {
1071:                    return "J";
1072:                } else if (clazz == float.class) {
1073:                    return "F";
1074:                } else if (clazz == double.class) {
1075:                    return "D";
1076:                } else if (clazz == boolean.class) {
1077:                    return "Z";
1078:                } else if (clazz == void.class) {
1079:                    return "V";
1080:                } else if (clazz.isArray()) {
1081:                    return "[" + signature(clazz.getComponentType());
1082:                } else {
1083:                    return "L" + clazz.getName().replace('.', '/') + ";";
1084:                }
1085:            }
1086:
1087:            public void addLineNumber(int line) {
1088:                LineNumberTable lineNumberTable = this .currentMethod.lineNumberTable;
1089:                if (lineNumberTable == null) {
1090:                    short idx = constantPool.addUTF8("LineNumberTable");
1091:                    lineNumberTable = new LineNumberTable(idx);
1092:                    this .currentMethod.lineNumberTable = lineNumberTable;
1093:                }
1094:                lineNumberTable.addLine(codeSize(), line);
1095:            }
1096:
1097:            public String toString() {
1098:                return getClass().getName() + "[" + className + "]";
1099:            }
1100:
1101:            static class ExceptionAttr {
1102:                private short nameIndex;
1103:
1104:                private short[] exceptionIndex;
1105:
1106:                ExceptionAttr(short nameIndex, short[] exceptionIndex) {
1107:                    this .nameIndex = nameIndex;
1108:                    this .exceptionIndex = exceptionIndex;
1109:                }
1110:
1111:                void write(DataOutputStream out) throws IOException {
1112:                    out.writeShort(nameIndex);
1113:                    int n = exceptionIndex.length;
1114:                    out.writeInt(n * 2 + 2);
1115:                    out.writeShort(n);
1116:                    for (int i = 0; i < n; i++) {
1117:                        out.writeShort(exceptionIndex[i]);
1118:                    }
1119:                }
1120:            }
1121:
1122:            static class MethodInfo {
1123:
1124:                short nameIndex;
1125:
1126:                short descriptorIndex;
1127:
1128:                short accessFlags;
1129:
1130:                ExceptionAttr exceptions;
1131:
1132:                ByteBuffer codeAttribute;
1133:
1134:                LineNumberTable lineNumberTable;
1135:
1136:                MethodInfo(short nameIndex, short descriptorIndex,
1137:                        short accessFlags, ExceptionAttr exceptions) {
1138:                    this .nameIndex = nameIndex;
1139:                    this .descriptorIndex = descriptorIndex;
1140:                    this .accessFlags = accessFlags;
1141:                    this .exceptions = exceptions;
1142:                }
1143:
1144:                ByteBuffer getCodeAttribute() {
1145:                    return this .codeAttribute;
1146:                }
1147:
1148:                void setCodeAttribute(ByteBuffer codeAttribute) {
1149:                    this .codeAttribute = codeAttribute;
1150:                }
1151:
1152:                void write(DataOutputStream out) throws IOException {
1153:                    out.writeShort(accessFlags);
1154:                    out.writeShort(nameIndex);
1155:                    out.writeShort(descriptorIndex);
1156:                    int count = 0;
1157:                    if (codeAttribute != null) {
1158:                        count++;
1159:                    }
1160:                    if (exceptions != null) {
1161:                        count++;
1162:                    }
1163:                    out.writeShort(count);
1164:                    if (exceptions != null) {
1165:                        exceptions.write(out);
1166:                    }
1167:                    if (codeAttribute != null) {
1168:                        codeAttribute.writeTo(out);
1169:                    }
1170:                    if (lineNumberTable != null) {
1171:                        lineNumberTable.write(out);
1172:                    }
1173:                }
1174:            }
1175:
1176:            static class FieldInfo {
1177:
1178:                private short nameIndex;
1179:
1180:                private short descriptorIndex;
1181:
1182:                private short accessFlags;
1183:
1184:                private short attributes[];
1185:
1186:                FieldInfo(short nameIndex, short descriptorIndex,
1187:                        short accessFlags) {
1188:                    this .nameIndex = nameIndex;
1189:                    this .descriptorIndex = descriptorIndex;
1190:                    this .accessFlags = accessFlags;
1191:                }
1192:
1193:                FieldInfo(short nameIndex, short descriptorIndex,
1194:                        short accessFlags, short attributes[]) {
1195:                    this .nameIndex = nameIndex;
1196:                    this .descriptorIndex = descriptorIndex;
1197:                    this .accessFlags = accessFlags;
1198:                    this .attributes = attributes;
1199:                }
1200:
1201:                void write(DataOutputStream out) throws IOException {
1202:                    out.writeShort(accessFlags);
1203:                    out.writeShort(nameIndex);
1204:                    out.writeShort(descriptorIndex);
1205:                    if (attributes == null) {
1206:                        out.writeShort(0); // no attributes
1207:                    } else {
1208:                        out.writeShort(1);
1209:                        out.writeShort(attributes[0]);
1210:                        out.writeShort(attributes[1]);
1211:                        out.writeShort(attributes[2]);
1212:                        out.writeShort(attributes[3]);
1213:                    }
1214:                }
1215:            }
1216:
1217:            static class ExceptionTableEntry {
1218:
1219:                Label start;
1220:
1221:                Label end;
1222:
1223:                Label handler;
1224:
1225:                short catchType;
1226:
1227:                ExceptionTableEntry(Label start, Label end, Label handler,
1228:                        short catchType) {
1229:                    this .start = start;
1230:                    this .end = end;
1231:                    this .handler = handler;
1232:                    this .catchType = catchType;
1233:                }
1234:            }
1235:
1236:            static class LineNumberTable {
1237:                IntArray pcArray;
1238:                IntArray lineArray;
1239:                short idx;
1240:
1241:                LineNumberTable(short attributeNameIndex) {
1242:                    this .pcArray = new IntArray();
1243:                    this .lineArray = new IntArray();
1244:                    this .idx = attributeNameIndex;
1245:                }
1246:
1247:                public void addLine(int pc, int line) {
1248:                    pcArray.add(pc);
1249:                    lineArray.add(line);
1250:                }
1251:
1252:                public int size() {
1253:                    return pcArray.size();
1254:                }
1255:
1256:                public void shift(int offset) {
1257:                    int size = pcArray.size();
1258:                    int[] pa = pcArray.getArray();
1259:                    for (int i = 0; i < size; i++) {
1260:                        pa[i] += offset;
1261:                    }
1262:                }
1263:
1264:                void write(DataOutputStream out) throws IOException {
1265:                    out.writeShort(idx);
1266:                    int size = pcArray.size();
1267:                    out.writeInt(2 + 4 * size);
1268:                    out.writeShort((short) size);
1269:                    int[] pa = pcArray.getArray();
1270:                    int[] la = lineArray.getArray();
1271:                    for (int i = 0; i < size; i++) {
1272:                        out.writeShort((short) pa[i]);
1273:                        out.writeShort((short) la[i]);
1274:                    }
1275:                }
1276:            }
1277:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.