Source Code Cross Referenced for MethodInfo.java in  » 6.0-JDK-Modules » j2me » components » 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 » 6.0 JDK Modules » j2me » components 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *   
0003:         *
0004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006:         * 
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License version
0009:         * 2 only, as published by the Free Software Foundation.
0010:         * 
0011:         * This program is distributed in the hope that it will be useful, but
0012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014:         * General Public License version 2 for more details (a copy is
0015:         * included at /legal/license.txt).
0016:         * 
0017:         * You should have received a copy of the GNU General Public License
0018:         * version 2 along with this work; if not, write to the Free Software
0019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA
0021:         * 
0022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023:         * Clara, CA 95054 or visit www.sun.com if you need additional
0024:         * information or have any questions.
0025:         */
0026:
0027:        package components;
0028:
0029:        import java.io.DataInput;
0030:        import java.io.DataOutput;
0031:        import java.io.IOException;
0032:        import java.io.PrintWriter;
0033:        import java.io.StringWriter;
0034:        import java.util.Hashtable;
0035:        import jcc.Const;
0036:        import jcc.EVMConst;
0037:        import jcc.Util;
0038:        import util.DataFormatException;
0039:
0040:        // Class for representing every method in a class
0041:
0042:        public class MethodInfo extends ClassMemberInfo implements  Const {
0043:            public int argsSize;
0044:            public int stack;
0045:            public int locals;
0046:            public int methodTableIndex = -1;
0047:
0048:            public byte code[];
0049:
0050:            private Attribute methodAttributes[];
0051:            public CodeAttribute codeAttribute;
0052:            public Attribute codeAttributes[];
0053:            public ExceptionEntry exceptionTable[];
0054:            public ClassConstant exceptionsThrown[];
0055:            private boolean checkedDebugTables = false;
0056:            private LineNumberTableEntry lineNumberTable[];
0057:            private LocalVariableTableEntry localVariableTable[];
0058:            public StackMapFrame stackMapTable[];
0059:            public vm.VMMethodInfo vmMethodInfo;
0060:
0061:            /* An array of the methods called by invokevirtual_quick and
0062:             * invokevirtualobject_quick.  (After quickening, before inlining). 
0063:             */
0064:            public MethodInfo[] targetMethods;
0065:
0066:            /**
0067:             * The following are arrays of indexes into the
0068:             * code array of references to the constant pool:
0069:             * ldcInstructions lists the instructions with a one-byte index.
0070:             * wideConstantRefInstructions lists the instructions with a two-byte index.
0071:             * In each case, the index is that of the opcode: the actual reference
0072:             * begins with the following byte.
0073:             * Entries of value -1 are ignored.
0074:             */
0075:            public int ldcInstructions[];
0076:            public int wideConstantRefInstructions[];
0077:
0078:            public MethodInfo(int name, int sig, int access, ClassInfo p) {
0079:                super (name, sig, access, p);
0080:            }
0081:
0082:            public void initializeClassDebugTables() {
0083:                int nattr = (codeAttributes == null) ? 0
0084:                        : codeAttributes.length;
0085:                // parse code attributes
0086:                for (int i = 0; i < nattr; i++) {
0087:                    Attribute a = codeAttributes[i];
0088:                    if (a.name.string.equals("LineNumberTable")) {
0089:                        lineNumberTable = ((LineNumberTableAttribute) a).data;
0090:                    }
0091:                    if (a.name.string.equals("LocalVariableTable")) {
0092:                        localVariableTable = ((LocalVariableTableAttribute) a).data;
0093:                    }
0094:                    if (a.name.string.equals("StackMap")) {
0095:                        stackMapTable = ((StackMapAttribute) a).data;
0096:                    }
0097:
0098:                }
0099:            }
0100:
0101:            public LineNumberTableEntry[] getLineNumberTable() {
0102:                if (!checkedDebugTables) {
0103:                    initializeClassDebugTables();
0104:                    checkedDebugTables = true;
0105:                }
0106:                return lineNumberTable;
0107:            }
0108:
0109:            public LocalVariableTableEntry[] getLocalVariableTable() {
0110:                if (!checkedDebugTables) {
0111:                    initializeClassDebugTables();
0112:                    checkedDebugTables = true;
0113:                }
0114:                return localVariableTable;
0115:            }
0116:
0117:            public boolean hasLineNumberTable() {
0118:                if (!checkedDebugTables) {
0119:                    initializeClassDebugTables();
0120:                    checkedDebugTables = true;
0121:                }
0122:                return (lineNumberTable != null)
0123:                        && (lineNumberTable.length != 0);
0124:            }
0125:
0126:            public boolean hasLocalVariableTable() {
0127:                if (!checkedDebugTables) {
0128:                    initializeClassDebugTables();
0129:                    checkedDebugTables = true;
0130:                }
0131:                return (localVariableTable != null)
0132:                        && (localVariableTable.length != 0);
0133:            }
0134:
0135:            public boolean throwsExceptions() {
0136:                return exceptionsThrown != null;
0137:            }
0138:
0139:            public ClassConstant[] getExceptionsThrown() {
0140:                return exceptionsThrown;
0141:            }
0142:
0143:            public int nExceptionsThrown() {
0144:                return (exceptionsThrown == null) ? 0 : exceptionsThrown.length;
0145:            }
0146:
0147:            private String nativeName;
0148:
0149:            public String getNativeName(boolean isJNI) {
0150:                if (nativeName == null) {
0151:                    nativeName = isJNI ? getJNIName() : getOldNativeName();
0152:                }
0153:                return nativeName;
0154:            }
0155:
0156:            public String getJNIReturnType() {
0157:                return Util.parseReturnType(this .type.string);
0158:            }
0159:
0160:            private String getJNIName() {
0161:                ClassInfo ci = parent;
0162:                String classname = ci.className;
0163:                String methodname = this .name.string;
0164:                int nmethods = ci.methods.length;
0165:                String typeName = null; // by default, don't need type
0166:                for (int j = 0; j < nmethods; j++) {
0167:                    MethodInfo m = ci.methods[j];
0168:                    if ((m != this ) && ((m.access & Const.ACC_NATIVE) != 0)) {
0169:                        if (m.name.equals(this .name)) {
0170:                            // Two native methods with the same name.  Need type name
0171:                            typeName = this .type.string;
0172:                            break;
0173:                        }
0174:                    }
0175:                }
0176:                return Util.convertToJNIName(classname, methodname, typeName);
0177:            }
0178:
0179:            private String getOldNativeName() {
0180:                ClassInfo ci = parent;
0181:                String methodname = this .name.string;
0182:                StringBuffer sbuf = new StringBuffer(/*NOI18N*/"Java_")
0183:                        .append(ci.getGenericNativeName()).append('_');
0184:                if (methodname.indexOf('_') == -1) {
0185:                    // optimization.  Most methods don't have an _ in them
0186:                    sbuf.append(methodname);
0187:                } else {
0188:                    for (int i = 0; i < methodname.length(); i++) {
0189:                        if (methodname.charAt(i) == '_') {
0190:                            sbuf.append(/*NOI18N*/"_0005f");
0191:                        } else {
0192:                            sbuf.append(methodname.charAt(i));
0193:                        }
0194:                    }
0195:                }
0196:                sbuf.append("_stub");
0197:                return sbuf.toString();
0198:            }
0199:
0200:            /*
0201:             * A methods attributes are Code and Exceptions.
0202:             */
0203:            private static Hashtable methodAttributeTypes = new Hashtable();
0204:
0205:            static {
0206:                methodAttributeTypes.put("Code", CodeAttributeFactory.instance);
0207:                methodAttributeTypes.put("Exceptions",
0208:                        ExceptionsAttributeFactory.instance);
0209:            }
0210:
0211:            // Read in method attributes from classfile
0212:            void readAttributes(DataInput in, ConstantObject locals[],
0213:                    ConstantObject globals[], boolean readCode)
0214:                    throws IOException {
0215:
0216:                methodAttributes = Attribute.readAttributes(in, locals,
0217:                        globals, methodAttributeTypes, false);
0218:
0219:                // oops, we read the code.
0220:                // we'll fix this someday.
0221:
0222:                //
0223:                // parse special attributes
0224:                //
0225:                if (methodAttributes != null) {
0226:                    for (int i = 0; i < methodAttributes.length; i++) {
0227:                        Attribute a = methodAttributes[i];
0228:                        if (a.name.string.equals("Code")) {
0229:                            CodeAttribute ca = (CodeAttribute) a;
0230:                            this .locals = ca.locals;
0231:                            this .stack = ca.stack;
0232:                            this .code = ca.code;
0233:                            this .exceptionTable = ca.exceptionTable;
0234:                            this .codeAttributes = ca.codeAttributes;
0235:                            this .codeAttribute = ca;
0236:                        } else if (a.name.string.equals("Exceptions")) {
0237:                            this .exceptionsThrown = ((ExceptionsAttribute) a).data;
0238:                        }
0239:                    }
0240:                }
0241:
0242:            }
0243:
0244:            public static MethodInfo readMethod(DataInput in, ClassInfo p,
0245:                    boolean readCode) throws IOException {
0246:                int access = in.readUnsignedShort();
0247:                int name = in.readUnsignedShort();
0248:                int sig = in.readUnsignedShort();
0249:                MethodInfo m = new MethodInfo(name, sig, access, p);
0250:                // the bad thing is, we really cannot go far
0251:                // without resolving. So we resolve here.
0252:                m.resolve(p.symbols);
0253:
0254:                m.argsSize = Util.argsSize(m.type.string);
0255:                if ((m.access & ACC_STATIC) == 0) {
0256:                    m.argsSize++;
0257:                }
0258:
0259:                m.readAttributes(in, p.constants, p.symbols, readCode);
0260:                return m;
0261:            }
0262:
0263:            public void externalize(ConstantPool p) {
0264:                super .externalize(p);
0265:                Attribute.externalizeAttributes(methodAttributes, p);
0266:                Attribute.externalizeAttributes(codeAttributes, p);
0267:            }
0268:
0269:            public void write(DataOutput o) throws IOException {
0270:                o.writeShort(access);
0271:                o.writeShort(name.index);
0272:                o.writeShort(type.index);
0273:                Attribute.writeAttributes(methodAttributes, o, false);
0274:            }
0275:
0276:            private static int getInt(byte[] code, int w) {
0277:                return ((int) code[w] << 24)
0278:                        | (((int) code[w + 1] & 0xff) << 16)
0279:                        | (((int) code[w + 2] & 0xff) << 8)
0280:                        | ((int) code[w + 3] & 0xff);
0281:            }
0282:
0283:            public int getInt(int w) {
0284:                return getInt(code, w);
0285:            }
0286:
0287:            public int getUnsignedShort(int w) {
0288:                return (((int) code[w] & 0xff) << 8)
0289:                        | ((int) code[w + 1] & 0xff);
0290:            }
0291:
0292:            public int getShort(int w) {
0293:                return (((int) code[w]) << 8) | ((int) code[w + 1] & 0xff);
0294:            }
0295:
0296:            //
0297:            // Private Utility functions
0298:            private void putInt(byte array[], int offset, int val) {
0299:                array[offset] = (byte) ((val >> 24) & 0xFF);
0300:                array[offset + 1] = (byte) ((val >> 16) & 0xFF);
0301:                array[offset + 2] = (byte) ((val >> 8) & 0xFF);
0302:                array[offset + 3] = (byte) (val & 0xFF);
0303:            }
0304:
0305:            private void putShort(int w, short v) {
0306:                code[w] = (byte) (v >>> 8);
0307:                code[w + 1] = (byte) v;
0308:            }
0309:
0310:            public void findConstantReferences() throws DataFormatException {
0311:                if (code == null)
0312:                    return; // no code, no references.
0313:                int ldc[] = new int[code.length / 2];
0314:                int wide[] = new int[code.length / 3];
0315:                int nldc = 0;
0316:                int nwide = 0;
0317:                int ncode = code.length;
0318:                int opcode;
0319:                for (int i = 0; i < ncode; /*nothing*/) {
0320:                    switch (opcode = (int) code[i] & 0xff) {
0321:                    case opc_tableswitch:
0322:                        i = (i + 4) & ~3;
0323:                        int low = getInt(i + 4);
0324:                        int high = getInt(i + 8);
0325:                        i += (high - low + 1) * 4 + 12;
0326:                        break;
0327:
0328:                    case opc_lookupswitch:
0329:                        i = (i + 4) & ~3;
0330:                        int pairs = getInt(i + 4);
0331:                        i += pairs * 8 + 8;
0332:                        break;
0333:
0334:                    case opc_wide:
0335:                        switch ((int) code[i + 1] & 0xff) {
0336:                        case opc_aload:
0337:                        case opc_iload:
0338:                        case opc_fload:
0339:                        case opc_lload:
0340:                        case opc_dload:
0341:                        case opc_istore:
0342:                        case opc_astore:
0343:                        case opc_fstore:
0344:                        case opc_lstore:
0345:                        case opc_dstore:
0346:                        case opc_ret:
0347:                            i += 4;
0348:                            break;
0349:
0350:                        case opc_iinc:
0351:                            i += 6;
0352:                            break;
0353:
0354:                        default:
0355:                            throw new DataFormatException(parent.className
0356:                                    + "." + name.string + ": unknown wide "
0357:                                    + "instruction: " + code[i + 1]);
0358:                        }
0359:                        break;
0360:                    case opc_ldc:
0361:                        ldc[nldc++] = i;
0362:                        i += opcLengths[opcode];
0363:                        break;
0364:                    case opc_ldc_w:
0365:                    case opc_ldc2_w:
0366:                    case opc_getstatic:
0367:                    case opc_putstatic:
0368:                    case opc_getfield:
0369:                    case opc_putfield:
0370:                    case opc_invokevirtual:
0371:                    case opc_invokespecial:
0372:                    case opc_invokestatic:
0373:                    case opc_invokeinterface:
0374:                    case opc_new:
0375:                    case opc_anewarray:
0376:                    case opc_checkcast:
0377:                    case opc_instanceof :
0378:                    case opc_multianewarray:
0379:
0380:                    case opc_getstatic_fast:
0381:                    case opc_getstaticp_fast:
0382:                    case opc_getstatic2_fast:
0383:                    case opc_putstatic_fast:
0384:                    case opc_putstatic2_fast:
0385:                    case opc_invokevirtual_fast:
0386:                    case opc_invokespecial_fast:
0387:                    case opc_invokestatic_fast:
0388:                    case opc_invokeinterface_fast:
0389:                    case opc_new_fast:
0390:                    case opc_anewarray_fast:
0391:                    case opc_multianewarray_fast:
0392:                    case opc_checkcast_fast:
0393:                    case opc_instanceof _fast:
0394:                        wide[nwide++] = i;
0395:                        i += opcLengths[opcode];
0396:                        break;
0397:                    default:
0398:                        i += opcLengths[opcode];
0399:                        break;
0400:                    }
0401:                }
0402:                // not knowing any better, we allocated excess capacity.
0403:                // allocate and fill appropriately-sized arrays.
0404:                ldcInstructions = new int[nldc];
0405:                System.arraycopy(ldc, 0, ldcInstructions, 0, nldc);
0406:                ldc = null;
0407:                wideConstantRefInstructions = new int[nwide];
0408:                System
0409:                        .arraycopy(wide, 0, wideConstantRefInstructions, 0,
0410:                                nwide);
0411:                wide = null;
0412:            }
0413:
0414:            private static int opcodeLength(byte[] code, int pc) {
0415:                int old_pc;
0416:                int opcode = (int) code[pc] & 0xff;
0417:                switch (opcode) {
0418:
0419:                case opc_tableswitch:
0420:                    old_pc = pc;
0421:                    pc = (pc + 4) & ~3;
0422:                    int low = getInt(code, pc + 4);
0423:                    int high = getInt(code, pc + 8);
0424:                    pc += (high - low + 1) * 4 + 12;
0425:                    return pc - old_pc;
0426:
0427:                case opc_lookupswitch:
0428:                    old_pc = pc;
0429:                    pc = (pc + 4) & ~3;
0430:                    int pairs = getInt(code, pc + 4);
0431:                    pc += pairs * 8 + 8;
0432:                    return pc - old_pc;
0433:
0434:                case opc_wide:
0435:                    if (((int) code[pc + 1] & 0xff) == opc_iinc)
0436:                        return 6;
0437:                    return 4;
0438:
0439:                default:
0440:                    return opcLengths[opcode];
0441:                }
0442:            }
0443:
0444:            public int opcodeLength(int pc) {
0445:                return opcodeLength(code, pc);
0446:            }
0447:
0448:            public void countConstantReferences(ConstantObject table[],
0449:                    boolean isRelocatable) {
0450:                super .countConstantReferences();
0451:                Attribute.countConstantReferences(methodAttributes,
0452:                        isRelocatable);
0453:                Attribute
0454:                        .countConstantReferences(codeAttributes, isRelocatable);
0455:                if (code == null)
0456:                    return; // no code, no relocation
0457:                if (ldcInstructions != null) {
0458:                    int list[] = ldcInstructions;
0459:                    int n = list.length;
0460:                    for (int i = 0; i < n; i++) {
0461:                        int loc = list[i];
0462:                        if (loc == -1)
0463:                            continue;
0464:                        table[(int) code[loc + 1] & 0xff].incReference();
0465:                    }
0466:                }
0467:                if (wideConstantRefInstructions != null) {
0468:                    int list[] = wideConstantRefInstructions;
0469:                    int n = list.length;
0470:                    for (int i = 0; i < n; i++) {
0471:                        int loc = list[i];
0472:                        if (loc == -1)
0473:                            continue;
0474:                        table[getUnsignedShort(loc + 1)].incReference();
0475:                    }
0476:                }
0477:            }
0478:
0479:            public void relocateConstantReferences(ConstantObject table[])
0480:                    throws DataFormatException {
0481:                if (code == null)
0482:                    return; // no code, no relocation
0483:                if (ldcInstructions != null) {
0484:                    int list[] = ldcInstructions;
0485:                    int n = list.length;
0486:                    for (int i = 0; i < n; i++) {
0487:                        int j = list[i] + 1;
0488:                        if (j <= 0)
0489:                            continue;
0490:                        ConstantObject c = table[(int) code[j] & 0xff];
0491:                        if (c.shared)
0492:                            throw new DataFormatException(
0493:                                    "code reference to shared constant");
0494:                        int v = c.index;
0495:                        if (v < 0)
0496:                            throw new DataFormatException(
0497:                                    "code reference to deleted constant at "
0498:                                            + qualifiedName() + "+"
0499:                                            + Integer.toHexString(j));
0500:                        if (v > 255)
0501:                            throw new DataFormatException(
0502:                                    "ldc subscript out of range at "
0503:                                            + qualifiedName() + "+"
0504:                                            + Integer.toHexString(j));
0505:                        code[j] = (byte) v;
0506:                    }
0507:                }
0508:                if (wideConstantRefInstructions != null) {
0509:                    int list[] = wideConstantRefInstructions;
0510:                    int n = list.length;
0511:                    for (int i = 0; i < n; i++) {
0512:                        int j = list[i] + 1;
0513:                        if (j <= 0)
0514:                            continue;
0515:                        ConstantObject c = table[getUnsignedShort(j)];
0516:                        if (c.shared)
0517:                            throw new DataFormatException(
0518:                                    "code reference to shared constant at "
0519:                                            + qualifiedName() + "+"
0520:                                            + Integer.toHexString(j));
0521:                        int v = c.index;
0522:                        if (v < 0)
0523:                            throw new DataFormatException(
0524:                                    "code reference to deleted constant at "
0525:                                            + qualifiedName() + "+"
0526:                                            + Integer.toHexString(j));
0527:                        putShort(j, (short) v);
0528:                    }
0529:                }
0530:            }
0531:
0532:            public void replaceCode(int start, int end) {
0533:                replaceCode(start, end, new byte[0]);
0534:            }
0535:
0536:            public void replaceCode(int start, int end, int op1) {
0537:                byte code[] = { (byte) op1 };
0538:                replaceCode(start, end, code);
0539:            }
0540:
0541:            public void replaceCode(int start, int end, int op1, int op2) {
0542:                byte code[] = { (byte) op1, (byte) op2 };
0543:                replaceCode(start, end, code);
0544:            }
0545:
0546:            public void replaceCode(int start, int end, int op1, int op2,
0547:                    int op3) {
0548:                byte code[] = { (byte) op1, (byte) op2, (byte) op3 };
0549:                replaceCode(start, end, code);
0550:            }
0551:
0552:            public java.util.BitSet getLabelTargets() {
0553:                java.util.BitSet result = new java.util.BitSet();
0554:                int ncode = code.length;
0555:                int nextpc;
0556:
0557:                for (int pc = 0; pc < ncode; pc = nextpc) {
0558:                    nextpc = pc + opcodeLength(pc);
0559:                    int opcode = (int) code[pc] & 0xff;
0560:                    switch (opcode) {
0561:
0562:                    case opc_tableswitch:
0563:                    case opc_lookupswitch:
0564:                        int i = (pc + 4) & ~3;
0565:                        int delta = (opcode == opc_tableswitch) ? 4 : 8;
0566:                        result.set(pc + getInt(i)); // default
0567:                        for (i = i + 12; i < nextpc; i += delta)
0568:                            result.set(pc + getInt(i));
0569:                        break;
0570:
0571:                    case opc_jsr:
0572:                        result.set(pc + 3);
0573:                    case opc_goto:
0574:                    case opc_ifeq:
0575:                    case opc_ifge:
0576:                    case opc_ifgt:
0577:                    case opc_ifle:
0578:                    case opc_iflt:
0579:                    case opc_ifne:
0580:                    case opc_if_icmpeq:
0581:                    case opc_if_icmpne:
0582:                    case opc_if_icmpge:
0583:                    case opc_if_icmplt:
0584:                    case opc_if_icmpgt:
0585:                    case opc_if_icmple:
0586:                    case opc_if_acmpeq:
0587:                    case opc_if_acmpne:
0588:                    case opc_ifnull:
0589:                    case opc_ifnonnull:
0590:                        result.set(pc + getShort(pc + 1));
0591:                        break;
0592:
0593:                    case opc_jsr_w:
0594:                        result.set(pc + 5);
0595:                    case opc_goto_w:
0596:                        result.set(pc + getInt(pc + 1));
0597:                        break;
0598:                    }
0599:                }
0600:                return result;
0601:            }
0602:
0603:            public void replaceCode(int start, int end, byte[] replaceCode) {
0604:                if (end - start < replaceCode.length) {
0605:                    // System.out.println("  Cannot yet do expansion!!");
0606:                    return;
0607:                }
0608:                if (exceptionTable != null && exceptionTable.length > 0) {
0609:                    for (int i = 0; i < exceptionTable.length; i++) {
0610:                        int startPC = exceptionTable[i].startPC;
0611:                        int endPC = exceptionTable[i].endPC;
0612:                        if (startPC >= start && startPC < end)
0613:                            return;
0614:                        if (endPC >= start && endPC < end)
0615:                            return;
0616:                    }
0617:                }
0618:                int startExtra = start + replaceCode.length;
0619:                int extra = end - startExtra;
0620:
0621:                System.arraycopy(replaceCode, 0, code, start,
0622:                        replaceCode.length);
0623:
0624:                for (int i = startExtra; i < end; i++)
0625:                    code[i] = (byte) opc_nop;
0626:            }
0627:
0628:            public void disassemble() {
0629:                System.out.println(disassemble(code, 0, code.length));
0630:            }
0631:
0632:            public String disassemble(int start, int end) {
0633:                return disassemble(code, start, end);
0634:            }
0635:
0636:            /**
0637:             * Return the byte stored at a given index from the offset
0638:             * within code bytes
0639:             */
0640:            private static final int at(byte codeBytes[], int index) {
0641:                return codeBytes[index] & 0xFF;
0642:            }
0643:
0644:            /**
0645:             * Return the short stored at a given index from the offset
0646:             * within code bytes
0647:             */
0648:            private static final int shortAt(byte codeBytes[], int index) {
0649:                return ((codeBytes[index] & 0xFF) << 8)
0650:                        | (codeBytes[index + 1] & 0xFF);
0651:            }
0652:
0653:            public static String disassemble(byte[] codeBytes, int start,
0654:                    int end) {
0655:                // Output goes into a string
0656:                StringWriter sw = new StringWriter();
0657:                PrintWriter output = new PrintWriter(sw);
0658:
0659:                for (int offset = start; offset < end;) {
0660:                    int opcode = at(codeBytes, offset);
0661:
0662:                    if (offset > start)
0663:                        output.print("; ");
0664:
0665:                    output.print(opcodeName(opcode));
0666:
0667:                    switch (opcode) {
0668:                    case opc_aload:
0669:                    case opc_astore:
0670:                    case opc_fload:
0671:                    case opc_fstore:
0672:                    case opc_iload:
0673:                    case opc_istore:
0674:                    case opc_lload:
0675:                    case opc_lstore:
0676:                    case opc_dload:
0677:                    case opc_dstore:
0678:                    case opc_ret:
0679:                        output.print(" " + at(codeBytes, offset + 1));
0680:                        offset += 2;
0681:                        break;
0682:
0683:                    case opc_iinc:
0684:                        output.print(" " + at(codeBytes, offset + 1) + " "
0685:                                + (byte) at(codeBytes, offset + 2));
0686:                        offset += 3;
0687:                        break;
0688:
0689:                    case opc_newarray:
0690:                        switch (at(codeBytes, offset + 1)) {
0691:                        case T_INT:
0692:                            output.print(" int");
0693:                            break;
0694:                        case T_LONG:
0695:                            output.print(" long");
0696:                            break;
0697:                        case T_FLOAT:
0698:                            output.print(" float");
0699:                            break;
0700:                        case T_DOUBLE:
0701:                            output.print(" double");
0702:                            break;
0703:                        case T_CHAR:
0704:                            output.print(" char");
0705:                            break;
0706:                        case T_SHORT:
0707:                            output.print(" short");
0708:                            break;
0709:                        case T_BYTE:
0710:                            output.print(" byte");
0711:                            break;
0712:                        case T_BOOLEAN:
0713:                            output.print(" boolean");
0714:                            break;
0715:                        default:
0716:                            output.print(" BOGUS");
0717:                            break;
0718:                        }
0719:                        offset += 2;
0720:                        break;
0721:
0722:                    case opc_anewarray_fast:
0723:                    case opc_anewarray: {
0724:                        int index = shortAt(codeBytes, offset + 1);
0725:                        output.print(" class #" + index + " ");
0726:                        offset += 3;
0727:                        break;
0728:                    }
0729:
0730:                    case opc_sipush:
0731:                        output.print(" "
0732:                                + (short) shortAt(codeBytes, offset + 1));
0733:                        offset += 3;
0734:                        break;
0735:
0736:                    case opc_bipush:
0737:                        output.print(" " + (byte) at(codeBytes, offset + 1));
0738:                        offset += 2;
0739:                        break;
0740:
0741:                    case opc_ldc: {
0742:                        int index = at(codeBytes, offset + 1);
0743:                        output.print(" #" + index + " ");
0744:                        offset += 2;
0745:                        break;
0746:                    }
0747:
0748:                    case opc_getstatic_fast:
0749:                    case opc_getstaticp_fast:
0750:                    case opc_getstatic2_fast:
0751:                    case opc_putstatic_fast:
0752:                    case opc_putstatic2_fast:
0753:                    case opc_unused_d5:
0754:                    case opc_invokevirtual_fast:
0755:                    case opc_invokespecial_fast:
0756:                    case opc_invokestatic_fast:
0757:                    case opc_invokeinterface_fast:
0758:                    case opc_new_fast:
0759:                    case opc_multianewarray_fast:
0760:                    case opc_checkcast_fast:
0761:                    case opc_instanceof _fast:
0762:                    case opc_ldc_w:
0763:                    case opc_ldc2_w:
0764:                    case opc_instanceof :
0765:                    case opc_checkcast:
0766:                    case opc_new:
0767:                    case opc_putstatic:
0768:                    case opc_getstatic:
0769:                    case opc_putfield:
0770:                    case opc_getfield:
0771:                    case opc_invokevirtual:
0772:                    case opc_invokespecial:
0773:                    case opc_invokestatic: {
0774:                        int index = shortAt(codeBytes, offset + 1);
0775:                        output.print(" #" + index + " ");
0776:                        offset += 3;
0777:                        break;
0778:                    }
0779:
0780:                    case opc_getfield_fast:
0781:                    case opc_getfieldp_fast:
0782:                    case opc_getfield2_fast:
0783:                    case opc_putfield_fast:
0784:                    case opc_putfield2_fast: {
0785:                        int index = at(codeBytes, offset + 1);
0786:                        output.print(" [" + index + "] ");
0787:                        offset += 3;
0788:                        break;
0789:                    }
0790:
0791:                    case opc_jsr:
0792:                    case opc_goto:
0793:                    case opc_ifeq:
0794:                    case opc_ifge:
0795:                    case opc_ifgt:
0796:                    case opc_ifle:
0797:                    case opc_iflt:
0798:                    case opc_ifne:
0799:                    case opc_if_icmpeq:
0800:                    case opc_if_icmpne:
0801:                    case opc_if_icmpge:
0802:                    case opc_if_icmpgt:
0803:                    case opc_if_icmple:
0804:                    case opc_if_icmplt:
0805:                    case opc_if_acmpeq:
0806:                    case opc_if_acmpne:
0807:                    case opc_ifnull:
0808:                    case opc_ifnonnull: {
0809:                        int target = offset
0810:                                + (short) shortAt(codeBytes, offset + 1);
0811:                        output.print(" " + target);
0812:                        offset += 3;
0813:                        break;
0814:                    }
0815:
0816:                    default:
0817:                        offset += opcodeLength(codeBytes, offset);
0818:                        break;
0819:                    }
0820:                }
0821:
0822:                output.close();
0823:                return sw.toString();
0824:            }
0825:
0826:            public static String opcodeName(int opcode) {
0827:                return opcNames[opcode];
0828:            }
0829:
0830:            public String toString() {
0831:                String r = "Method: " + super .toString();
0832:                if (code != null) {
0833:                    r += " {" + code.length + " bytes of code}";
0834:                }
0835:                return r;
0836:            }
0837:
0838:            // Case 1: expand code.
0839:            // Convert ldc to ldc2: a. Insert extra bytes
0840:            //                      b. Fix all branch targets/exception ranges
0841:            // Case 2: smash code
0842:            // ldc_w_fast has index which is less than 255. Change to use
0843:            // ldc_w.
0844:            public void relocateAndPackCode(ConstantObject co[]) {
0845:
0846:                if (code == null)
0847:                    return;
0848:
0849:                int opcode, adjustment = 0;
0850:                int newOffsets[] = new int[code.length];
0851:                int indexByPC[] = new int[code.length];
0852:
0853:                // First figure out where we'll have to insert extra bytes in
0854:                // order to fit opc_ldc_w instead of opc_ldc instructions.
0855:                for (int pc = 0, pcindex = 0; pc < code.length; pc = pc
0856:                        + opcodeLength(pc), pcindex++) {
0857:                    opcode = (int) code[pc] & 0xFF;
0858:                    newOffsets[pcindex] = pc + adjustment;
0859:                    indexByPC[pc] = pcindex;
0860:
0861:                    /*******
0862:                     * switch (opcode) {
0863:                     *    case opc_ldc: {
0864:                     *        // a conversion table which maps pcValue to new index.
0865:                     *        int oldindex = (int)(code[pc+1] & 0xFF);
0866:                     *        int index = co[oldindex].index;
0867:                     *
0868:                     *        if (index >= 0x100)
0869:                     *            adjustment++;
0870:                     *        break;
0871:                     *    }
0872:                     *
0873:                     *
0874:                     *  case opc_ldc_w: {
0875:                     *      // a conversion table which maps pcValue to new index.
0876:                     *      int oldindex = (int)(((code[pc+1]&0xFF) << 8)
0877:                     *    		 | (code[pc+2]&0xFF));
0878:                     *      int index = co[oldindex].index;
0879:                     *
0880:                     *      if (index < 0x100)
0881:                     *          adjustment--;
0882:                     *      break;
0883:                     *  }
0884:                     *
0885:                     *
0886:                     *
0887:                     *  case opc_goto: {
0888:                     *      // Calculate the displacement, sign extend high byte
0889:                     *      int displ = (code[pc+1] << 8) | (code[pc+2] & 0xFF);
0890:                     *
0891:                     *      if (displ == 3) {
0892:                     *          adjustment -= 3; // remove no-use goto's.
0893:                     *      }
0894:                     *      break;
0895:                     *  }
0896:                     *
0897:                     *  case opc_nop: {
0898:                     *      adjustment--; // remove
0899:                     *      break;
0900:                     *  }
0901:                     *
0902:                     *
0903:                     *  case opc_tableswitch:
0904:                     *  case opc_lookupswitch: {
0905:                     *      int oldExtraPC = (( pc + 4 ) & ~3);
0906:                     *      int newExtraPC = (( pc + adjustment + 4) & ~3);
0907:                     *      adjustment = newExtraPC - oldExtraPC;
0908:                     *      break;
0909:                     *  }
0910:                     * }
0911:                     *******/
0912:                }
0913:
0914:                // Now copy the code to the new location. At the same
0915:                // time, we adjust all branch targets.
0916:                byte newCode[] = new byte[code.length + adjustment];
0917:
0918:                for (int pc = 0, pcindex = 0; pc < code.length; pc = pc
0919:                        + opcodeLength(pc), pcindex++) {
0920:                    int outPos = newOffsets[pcindex];
0921:                    int inPos = pc;
0922:
0923:                    opcode = (int) code[pc] & 0xFF;
0924:
0925:                    for (int i = 0; i < opcodeLength(pc); i++) {
0926:                        newCode[outPos + i] = code[pc + i];
0927:                    }
0928:
0929:                    switch (opcode) {
0930:                    case opc_ldc: {
0931:                        int oldindex = (int) (code[pc + 1] & 0xFF);
0932:                        int index = co[oldindex].index;
0933:                        if (index >= 0x100) {
0934:                            new RuntimeException("load constant overflow");
0935:                        }
0936:                        newCode[outPos + 1] = (byte) index;
0937:                        break;
0938:                    }
0939:
0940:                        /****
0941:                         *   // Remapping branches
0942:                         *   case opc_ifeq:
0943:                         *   case opc_ifne:
0944:                         *   case opc_iflt:
0945:                         *   case opc_ifge:
0946:                         *   case opc_ifgt:
0947:                         *   case opc_ifle:
0948:                         *   case opc_if_icmpeq:
0949:                         *   case opc_if_icmpne:
0950:                         *   case opc_if_icmplt:
0951:                         *   case opc_if_icmpge:
0952:                         *   case opc_if_icmpgt:
0953:                         *   case opc_if_icmple:
0954:                         *   case opc_if_acmpeq:
0955:                         *   case opc_if_acmpne:
0956:                         *   case opc_ifnull:
0957:                         *   case opc_ifnonnull:
0958:                         *   case opc_goto:
0959:                         *   case opc_jsr: {
0960:                         *       // Calculate the displacement, sign extend high byte
0961:                         *       int displ = (code[pc+1] << 8) | (code[pc+2] & 0xFF);
0962:                         *
0963:                         *      *  if (displ == 3 && opcode == opc_goto) {
0964:                         *      *     break;
0965:                         *      * }
0966:                         *
0967:
0968:                         *       int branchDest = pc + displ;
0969:                         *
0970:                         *       if ((code[branchDest] & 0xFF) == opc_goto) {
0971:                         *           // We're branching to a goto.  We can just branch to
0972:                         *           // where the goto was going.
0973:                         *           branchDest +=
0974:                         *     	(code[branchDest+1] << 8) | (code[branchDest+2] & 0xFF);
0975:                         *       }
0976:                         *       int newDest = newOffsets[indexByPC[branchDest]] - outPos;
0977:                         *       newCode[outPos+1] = (byte) ((newDest >> 8) & 0xFF);
0978:                         *       newCode[outPos+2] = (byte) (newDest & 0xFF);
0979:                         *       break;
0980:                         *   }
0981:                         *
0982:                         *   case opc_tableswitch: {
0983:                         *       newCode[outPos] = code[pc];
0984:                         *       outPos = (outPos + 4) & ~3;
0985:                         *       inPos = (inPos + 4) & ~3;
0986:                         *
0987:                         *       // Update the default destination
0988:                         *       int oldDest = getInt(inPos) + pc;
0989:                         *       int newDest = newOffsets[indexByPC[oldDest]]
0990:                         *     		- newOffsets[pcindex];
0991:                         *       putInt(newCode, outPos, newDest);
0992:                         *
0993:                         *       // Update each of the destinations in the table
0994:                         *       int low = getInt(inPos+4);
0995:                         *       int high = getInt(inPos+8);
0996:                         *       putInt(newCode, outPos+4, low);
0997:                         *       putInt(newCode, outPos+8, high);
0998:                         *       for (int j = 0; j <= high-low; j++) {
0999:                         *           int offset = j * 4 + 12;
1000:                         *           oldDest = getInt(inPos + offset) + pc;
1001:                         *           newDest = newOffsets[indexByPC[oldDest]]
1002:                         *     		- newOffsets[pcindex];
1003:                         *           putInt(newCode, outPos + offset, newDest);
1004:                         *       }
1005:                         *       break;
1006:                         *   }
1007:                         *
1008:                         *   case opc_lookupswitch: {
1009:                         *       newCode[outPos] = code[pc];
1010:                         *       // 0-3 byte pads
1011:                         *       outPos = (outPos + 4) & ~3;
1012:                         *       inPos = (inPos + 4) & ~3;
1013:                         *
1014:                         *       // Update the default destination
1015:                         *       int oldDest = getInt(inPos) + pc;
1016:                         *       int newDest = newOffsets[indexByPC[oldDest]]
1017:                         *     	        - newOffsets[pcindex];
1018:                         *       putInt(newCode, outPos, newDest);
1019:                         *
1020:                         *       // Update each of the pairs of destinations in the list
1021:                         *       int pairs = getInt(inPos+4);
1022:                         *       putInt(newCode, outPos+4, pairs);
1023:                         *       for (int j = 0; j < pairs; j++) {
1024:                         *           int offset = (j + 1) * 8;
1025:                         *
1026:                         *           // First copy the value
1027:                         *           putInt(newCode, outPos + offset,
1028:                         *                  getInt(inPos + offset));
1029:                         *           offset += 4;
1030:                         *
1031:                         *           // Now adjust the destination
1032:                         *           oldDest = getInt(inPos + offset) + pc;
1033:                         *           newDest = newOffsets[indexByPC[oldDest]]
1034:                         *     		- newOffsets[pcindex];
1035:                         *           putInt(newCode, outPos + offset, newDest);
1036:                         *       }
1037:                         *       break;
1038:                         *   }
1039:                         ********/
1040:
1041:                        // Byte-codes with constant pool access. Remap to new indices
1042:                    case opc_getfield:
1043:                    case opc_checkcast:
1044:                    case opc_getstatic:
1045:                    case opc_instanceof :
1046:                    case opc_ldc2_w:
1047:                    case opc_new:
1048:                    case opc_putfield:
1049:                    case opc_putstatic:
1050:                    case opc_invokevirtual:
1051:                    case opc_invokestatic:
1052:                    case opc_invokespecial:
1053:                    case opc_getstatic_fast:
1054:                    case opc_getstaticp_fast:
1055:                    case opc_getstatic2_fast:
1056:                    case opc_putstatic_fast:
1057:                    case opc_putstatic2_fast:
1058:                    case opc_invokevirtual_fast:
1059:                    case opc_invokespecial_fast:
1060:                    case opc_invokestatic_fast:
1061:                    case opc_anewarray_fast:
1062:                    case opc_checkcast_fast:
1063:                    case opc_instanceof _fast:
1064:                    case opc_multianewarray:
1065:                    case opc_multianewarray_fast:
1066:                    case opc_invokeinterface:
1067:                    case opc_invokeinterface_fast:
1068:                    case opc_ldc_w: {
1069:                        int oldindex = (int) (((code[pc + 1] & 0xFF) << 8) | (code[pc + 2] & 0xFF));
1070:                        int index = co[oldindex].index;
1071:                        newCode[outPos] = (byte) opcode;
1072:                        newCode[outPos + 1] = (byte) ((index >> 8) & 0xFF);
1073:                        newCode[outPos + 2] = (byte) (index & 0xFF);
1074:                        break;
1075:                    }
1076:                    }
1077:                }
1078:
1079:                // Update the exception table
1080:                for (int i = 0; i < exceptionTable.length; i++) {
1081:                    ExceptionEntry e = exceptionTable[i];
1082:                    e.startPC = newOffsets[indexByPC[e.startPC]];
1083:                    e.endPC = newOffsets[indexByPC[e.endPC]];
1084:                    e.handlerPC = newOffsets[indexByPC[e.handlerPC]];
1085:                }
1086:
1087:                // Update the line number table
1088:                LineNumberTableEntry[] lntab = getLineNumberTable();
1089:                if (lntab != null) {
1090:                    for (int i = 0; i < lntab.length; i++) {
1091:                        LineNumberTableEntry e = lntab[i];
1092:                        e.startPC = newOffsets[indexByPC[e.startPC]];
1093:                    }
1094:                }
1095:
1096:                // Update the line number table
1097:                LocalVariableTableEntry[] locvartab = getLocalVariableTable();
1098:                if (locvartab != null) {
1099:                    for (int i = 0; i < locvartab.length; i++) {
1100:                        LocalVariableTableEntry e = locvartab[i];
1101:                        e.pc0 = newOffsets[indexByPC[e.pc0]];
1102:                    }
1103:                }
1104:
1105:                // Update the stack maps
1106:                if (stackMapTable != null) {
1107:                    for (int i = 0; i < stackMapTable.length; i++) {
1108:                        StackMapFrame frame = stackMapTable[i];
1109:                        frame.offset = newOffsets[indexByPC[frame.offset]];
1110:                    }
1111:                }
1112:                // make the changes permanent
1113:                code = newCode;
1114:            }
1115:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.