Source Code Cross Referenced for CodeDisassembler.java in  » Byte-Code » Cojen » org » cojen » classfile » 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 » Byte Code » Cojen » org.cojen.classfile 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Copyright 2004 Brian S O'Neill
0003:         *
0004:         *  Licensed under the Apache License, Version 2.0 (the "License");
0005:         *  you may not use this file except in compliance with the License.
0006:         *  You may obtain a copy of the License at
0007:         *
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         *  Unless required by applicable law or agreed to in writing, software
0011:         *  distributed under the License is distributed on an "AS IS" BASIS,
0012:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         *  See the License for the specific language governing permissions and
0014:         *  limitations under the License.
0015:         */
0016:
0017:        package org.cojen.classfile;
0018:
0019:        import java.util.ArrayList;
0020:        import java.util.HashMap;
0021:        import java.util.List;
0022:        import java.util.Map;
0023:        import java.util.Vector;
0024:        import org.cojen.classfile.attribute.CodeAttr;
0025:        import org.cojen.classfile.constant.ConstantClassInfo;
0026:        import org.cojen.classfile.constant.ConstantDoubleInfo;
0027:        import org.cojen.classfile.constant.ConstantFieldInfo;
0028:        import org.cojen.classfile.constant.ConstantFloatInfo;
0029:        import org.cojen.classfile.constant.ConstantIntegerInfo;
0030:        import org.cojen.classfile.constant.ConstantInterfaceMethodInfo;
0031:        import org.cojen.classfile.constant.ConstantLongInfo;
0032:        import org.cojen.classfile.constant.ConstantMethodInfo;
0033:        import org.cojen.classfile.constant.ConstantNameAndTypeInfo;
0034:        import org.cojen.classfile.constant.ConstantStringInfo;
0035:
0036:        /**
0037:         * Disassembles a method into a CodeAssembler, which acts as a visitor.
0038:         *
0039:         * @author Brian S O'Neill
0040:         */
0041:        public class CodeDisassembler {
0042:            private final MethodInfo mMethod;
0043:            private final String mEnclosingClassName;
0044:            private final String mSuperClassName;
0045:            private final CodeAttr mCode;
0046:            private final ConstantPool mCp;
0047:            private final byte[] mByteCodes;
0048:            private final ExceptionHandler[] mExceptionHandlers;
0049:
0050:            // Current CodeAssembler in use for disassembly.
0051:            private CodeAssembler mAssembler;
0052:
0053:            // List of all the LocalVariable objects in use.
0054:            private Vector mLocals;
0055:
0056:            // True if the method being decompiled still has a "this" reference.
0057:            private boolean mHasThis;
0058:
0059:            private Location mReturnLocation;
0060:
0061:            // Maps Integer address keys to itself, but to Label objects after first
0062:            // needed.
0063:            private Map mLabels;
0064:
0065:            // Maps Integer catch locations to Lists of ExceptionHandler objects.
0066:            private Map mCatchLocations;
0067:
0068:            // Current address being decompiled.
0069:            private int mAddress;
0070:
0071:            /**
0072:             * @throws IllegalArgumentException if method has no code
0073:             */
0074:            public CodeDisassembler(MethodInfo method)
0075:                    throws IllegalArgumentException {
0076:                mMethod = method;
0077:                mEnclosingClassName = method.getClassFile().getClassName();
0078:                mSuperClassName = method.getClassFile().getSuperClassName();
0079:                if ((mCode = method.getCodeAttr()) == null) {
0080:                    throw new IllegalArgumentException("Method defines no code");
0081:                }
0082:                mCp = mCode.getConstantPool();
0083:                CodeBuffer buffer = mCode.getCodeBuffer();
0084:                mByteCodes = buffer.getByteCodes();
0085:                mExceptionHandlers = buffer.getExceptionHandlers();
0086:            }
0087:
0088:            /**
0089:             * Disassemble the MethodInfo into the given assembler.
0090:             *
0091:             * @see CodeAssemblerPrinter
0092:             */
0093:            public void disassemble(CodeAssembler assembler) {
0094:                disassemble(assembler, null, null);
0095:            }
0096:
0097:            /**
0098:             * Disassemble the MethodInfo into the given assembler.
0099:             *
0100:             * @param params if not null, override the local variables which hold parameter values
0101:             * @param returnLocation if not null, disassemble will branch to this location upon seeing
0102:             * a return, leaving any arguments on the stack
0103:             * @see CodeAssemblerPrinter
0104:             */
0105:            public synchronized void disassemble(CodeAssembler assembler,
0106:                    LocalVariable[] params, Location returnLocation) {
0107:                mAssembler = assembler;
0108:                mLocals = new Vector();
0109:                if (mHasThis = !mMethod.getModifiers().isStatic()) {
0110:                    // Reserve a slot for "this" parameter.
0111:                    mLocals.add(null);
0112:                }
0113:
0114:                gatherLabels();
0115:
0116:                // Gather the local variables of the parameters.
0117:                {
0118:                    TypeDesc[] paramTypes = mMethod.getMethodDescriptor()
0119:                            .getParameterTypes();
0120:
0121:                    if (params == null) {
0122:                        params = new LocalVariable[assembler
0123:                                .getParameterCount()];
0124:                        for (int i = params.length; --i >= 0;) {
0125:                            params[i] = assembler.getParameter(i);
0126:                        }
0127:                    }
0128:                    if (paramTypes.length != params.length) {
0129:                        throw new IllegalArgumentException(
0130:                                "Method parameter count doesn't match given parameter count: "
0131:                                        + paramTypes.length + " != "
0132:                                        + params.length);
0133:                    }
0134:
0135:                    for (int i = 0; i < paramTypes.length; i++) {
0136:                        LocalVariable paramVar = params[i];
0137:                        if (!compatibleType(paramTypes[i], paramVar.getType())) {
0138:                            throw new IllegalArgumentException(
0139:                                    "Method parameter type is not compatible with given type: "
0140:                                            + paramTypes[i] + " != "
0141:                                            + paramVar.getType());
0142:                        }
0143:                        mLocals.add(paramVar);
0144:                        if (paramVar.getType().isDoubleWord()) {
0145:                            // Reserve slot for least significant word.
0146:                            mLocals.add(null);
0147:                        }
0148:                    }
0149:                }
0150:
0151:                mReturnLocation = returnLocation;
0152:
0153:                Location currentLoc = new Location() {
0154:                    public int getLocation() {
0155:                        return mAddress;
0156:                    }
0157:
0158:                    public int compareTo(Object obj) {
0159:                        if (this  == obj) {
0160:                            return 0;
0161:                        }
0162:                        Location other = (Location) obj;
0163:
0164:                        int loca = getLocation();
0165:                        int locb = other.getLocation();
0166:
0167:                        if (loca < locb) {
0168:                            return -1;
0169:                        } else if (loca > locb) {
0170:                            return 1;
0171:                        } else {
0172:                            return 0;
0173:                        }
0174:                    }
0175:                };
0176:
0177:                int currentLine = -1;
0178:
0179:                for (mAddress = 0; mAddress < mByteCodes.length; mAddress++) {
0180:                    int nextLine = mCode.getLineNumber(currentLoc);
0181:                    if (nextLine != currentLine) {
0182:                        if ((currentLine = nextLine) >= 0) {
0183:                            mAssembler.mapLineNumber(currentLine);
0184:                        }
0185:                    }
0186:
0187:                    // Check if a label needs to be created and/or located.
0188:                    locateLabel();
0189:
0190:                    byte opcode = mByteCodes[mAddress];
0191:
0192:                    int index;
0193:                    Location loc;
0194:                    TypeDesc type;
0195:                    ConstantInfo ci;
0196:
0197:                    switch (opcode) {
0198:
0199:                    default:
0200:                        error(opcode, "Unknown opcode: " + (opcode & 0xff));
0201:                        break;
0202:
0203:                    // Opcodes with no operands...
0204:
0205:                    case Opcode.NOP:
0206:                        assembler.nop();
0207:                        break;
0208:                    case Opcode.BREAKPOINT:
0209:                        assembler.breakpoint();
0210:                        break;
0211:
0212:                    case Opcode.ACONST_NULL:
0213:                        assembler.loadNull();
0214:                        break;
0215:                    case Opcode.ICONST_M1:
0216:                        assembler.loadConstant(-1);
0217:                        break;
0218:                    case Opcode.ICONST_0:
0219:                        assembler.loadConstant(0);
0220:                        break;
0221:                    case Opcode.ICONST_1:
0222:                        assembler.loadConstant(1);
0223:                        break;
0224:                    case Opcode.ICONST_2:
0225:                        assembler.loadConstant(2);
0226:                        break;
0227:                    case Opcode.ICONST_3:
0228:                        assembler.loadConstant(3);
0229:                        break;
0230:                    case Opcode.ICONST_4:
0231:                        assembler.loadConstant(4);
0232:                        break;
0233:                    case Opcode.ICONST_5:
0234:                        assembler.loadConstant(5);
0235:                        break;
0236:                    case Opcode.LCONST_0:
0237:                        assembler.loadConstant(0L);
0238:                        break;
0239:                    case Opcode.LCONST_1:
0240:                        assembler.loadConstant(1L);
0241:                        break;
0242:                    case Opcode.FCONST_0:
0243:                        assembler.loadConstant(0f);
0244:                        break;
0245:                    case Opcode.FCONST_1:
0246:                        assembler.loadConstant(1f);
0247:                        break;
0248:                    case Opcode.FCONST_2:
0249:                        assembler.loadConstant(2f);
0250:                        break;
0251:                    case Opcode.DCONST_0:
0252:                        assembler.loadConstant(0d);
0253:                        break;
0254:                    case Opcode.DCONST_1:
0255:                        assembler.loadConstant(1d);
0256:                        break;
0257:
0258:                    case Opcode.POP:
0259:                        assembler.pop();
0260:                        break;
0261:                    case Opcode.POP2:
0262:                        assembler.pop2();
0263:                        break;
0264:                    case Opcode.DUP:
0265:                        assembler.dup();
0266:                        break;
0267:                    case Opcode.DUP_X1:
0268:                        assembler.dupX1();
0269:                        break;
0270:                    case Opcode.DUP_X2:
0271:                        assembler.dupX2();
0272:                        break;
0273:                    case Opcode.DUP2:
0274:                        assembler.dup2();
0275:                        break;
0276:                    case Opcode.DUP2_X1:
0277:                        assembler.dup2X2();
0278:                        break;
0279:                    case Opcode.DUP2_X2:
0280:                        assembler.dup2X2();
0281:                        break;
0282:                    case Opcode.SWAP:
0283:                        assembler.swap();
0284:                        break;
0285:
0286:                    case Opcode.IADD:
0287:                    case Opcode.LADD:
0288:                    case Opcode.FADD:
0289:                    case Opcode.DADD:
0290:                    case Opcode.ISUB:
0291:                    case Opcode.LSUB:
0292:                    case Opcode.FSUB:
0293:                    case Opcode.DSUB:
0294:                    case Opcode.IMUL:
0295:                    case Opcode.LMUL:
0296:                    case Opcode.FMUL:
0297:                    case Opcode.DMUL:
0298:                    case Opcode.IDIV:
0299:                    case Opcode.LDIV:
0300:                    case Opcode.FDIV:
0301:                    case Opcode.DDIV:
0302:                    case Opcode.IREM:
0303:                    case Opcode.LREM:
0304:                    case Opcode.FREM:
0305:                    case Opcode.DREM:
0306:                    case Opcode.INEG:
0307:                    case Opcode.LNEG:
0308:                    case Opcode.FNEG:
0309:                    case Opcode.DNEG:
0310:                    case Opcode.ISHL:
0311:                    case Opcode.LSHL:
0312:                    case Opcode.ISHR:
0313:                    case Opcode.LSHR:
0314:                    case Opcode.IUSHR:
0315:                    case Opcode.LUSHR:
0316:                    case Opcode.IAND:
0317:                    case Opcode.LAND:
0318:                    case Opcode.IOR:
0319:                    case Opcode.LOR:
0320:                    case Opcode.IXOR:
0321:                    case Opcode.LXOR:
0322:                    case Opcode.FCMPL:
0323:                    case Opcode.DCMPL:
0324:                    case Opcode.FCMPG:
0325:                    case Opcode.DCMPG:
0326:                    case Opcode.LCMP:
0327:                        assembler.math(opcode);
0328:                        break;
0329:
0330:                    case Opcode.I2L:
0331:                        assembler.convert(TypeDesc.INT, TypeDesc.LONG);
0332:                        break;
0333:                    case Opcode.I2F:
0334:                        assembler.convert(TypeDesc.INT, TypeDesc.FLOAT);
0335:                        break;
0336:                    case Opcode.I2D:
0337:                        assembler.convert(TypeDesc.INT, TypeDesc.DOUBLE);
0338:                        break;
0339:                    case Opcode.L2I:
0340:                        assembler.convert(TypeDesc.LONG, TypeDesc.INT);
0341:                        break;
0342:                    case Opcode.L2F:
0343:                        assembler.convert(TypeDesc.LONG, TypeDesc.FLOAT);
0344:                        break;
0345:                    case Opcode.L2D:
0346:                        assembler.convert(TypeDesc.LONG, TypeDesc.DOUBLE);
0347:                        break;
0348:                    case Opcode.F2I:
0349:                        assembler.convert(TypeDesc.FLOAT, TypeDesc.INT);
0350:                        break;
0351:                    case Opcode.F2L:
0352:                        assembler.convert(TypeDesc.FLOAT, TypeDesc.LONG);
0353:                        break;
0354:                    case Opcode.F2D:
0355:                        assembler.convert(TypeDesc.FLOAT, TypeDesc.DOUBLE);
0356:                        break;
0357:                    case Opcode.D2I:
0358:                        assembler.convert(TypeDesc.DOUBLE, TypeDesc.INT);
0359:                        break;
0360:                    case Opcode.D2L:
0361:                        assembler.convert(TypeDesc.DOUBLE, TypeDesc.LONG);
0362:                        break;
0363:                    case Opcode.D2F:
0364:                        assembler.convert(TypeDesc.DOUBLE, TypeDesc.FLOAT);
0365:                        break;
0366:                    case Opcode.I2B:
0367:                        assembler.convert(TypeDesc.INT, TypeDesc.BYTE);
0368:                        break;
0369:                    case Opcode.I2C:
0370:                        assembler.convert(TypeDesc.INT, TypeDesc.CHAR);
0371:                        break;
0372:                    case Opcode.I2S:
0373:                        assembler.convert(TypeDesc.INT, TypeDesc.SHORT);
0374:                        break;
0375:
0376:                    case Opcode.IRETURN:
0377:                    case Opcode.LRETURN:
0378:                    case Opcode.FRETURN:
0379:                    case Opcode.DRETURN:
0380:                    case Opcode.ARETURN:
0381:                    case Opcode.RETURN:
0382:                        if (mReturnLocation != null) {
0383:                            assembler.branch(mReturnLocation);
0384:                        } else {
0385:                            switch (opcode) {
0386:                            case Opcode.IRETURN:
0387:                                assembler.returnValue(TypeDesc.INT);
0388:                                break;
0389:                            case Opcode.LRETURN:
0390:                                assembler.returnValue(TypeDesc.LONG);
0391:                                break;
0392:                            case Opcode.FRETURN:
0393:                                assembler.returnValue(TypeDesc.FLOAT);
0394:                                break;
0395:                            case Opcode.DRETURN:
0396:                                assembler.returnValue(TypeDesc.DOUBLE);
0397:                                break;
0398:                            case Opcode.ARETURN:
0399:                                assembler.returnValue(TypeDesc.OBJECT);
0400:                                break;
0401:                            case Opcode.RETURN:
0402:                                assembler.returnVoid();
0403:                                break;
0404:                            }
0405:                        }
0406:                        break;
0407:
0408:                    case Opcode.IALOAD:
0409:                        assembler.loadFromArray(TypeDesc.INT);
0410:                        break;
0411:                    case Opcode.LALOAD:
0412:                        assembler.loadFromArray(TypeDesc.LONG);
0413:                        break;
0414:                    case Opcode.FALOAD:
0415:                        assembler.loadFromArray(TypeDesc.FLOAT);
0416:                        break;
0417:                    case Opcode.DALOAD:
0418:                        assembler.loadFromArray(TypeDesc.DOUBLE);
0419:                        break;
0420:                    case Opcode.AALOAD:
0421:                        assembler.loadFromArray(TypeDesc.OBJECT);
0422:                        break;
0423:                    case Opcode.BALOAD:
0424:                        assembler.loadFromArray(TypeDesc.BYTE);
0425:                        break;
0426:                    case Opcode.CALOAD:
0427:                        assembler.loadFromArray(TypeDesc.CHAR);
0428:                        break;
0429:                    case Opcode.SALOAD:
0430:                        assembler.loadFromArray(TypeDesc.SHORT);
0431:                        break;
0432:
0433:                    case Opcode.IASTORE:
0434:                        assembler.storeToArray(TypeDesc.INT);
0435:                        break;
0436:                    case Opcode.LASTORE:
0437:                        assembler.storeToArray(TypeDesc.LONG);
0438:                        break;
0439:                    case Opcode.FASTORE:
0440:                        assembler.storeToArray(TypeDesc.FLOAT);
0441:                        break;
0442:                    case Opcode.DASTORE:
0443:                        assembler.storeToArray(TypeDesc.DOUBLE);
0444:                        break;
0445:                    case Opcode.AASTORE:
0446:                        assembler.storeToArray(TypeDesc.OBJECT);
0447:                        break;
0448:                    case Opcode.BASTORE:
0449:                        assembler.storeToArray(TypeDesc.BYTE);
0450:                        break;
0451:                    case Opcode.CASTORE:
0452:                        assembler.storeToArray(TypeDesc.CHAR);
0453:                        break;
0454:                    case Opcode.SASTORE:
0455:                        assembler.storeToArray(TypeDesc.SHORT);
0456:                        break;
0457:
0458:                    case Opcode.ARRAYLENGTH:
0459:                        assembler.arrayLength();
0460:                        break;
0461:                    case Opcode.ATHROW:
0462:                        assembler.throwObject();
0463:                        break;
0464:                    case Opcode.MONITORENTER:
0465:                        assembler.monitorEnter();
0466:                        break;
0467:                    case Opcode.MONITOREXIT:
0468:                        assembler.monitorExit();
0469:                        break;
0470:
0471:                    // End opcodes with no operands.
0472:
0473:                    // Opcodes that load a constant from the constant pool...
0474:
0475:                    case Opcode.LDC:
0476:                    case Opcode.LDC_W:
0477:                    case Opcode.LDC2_W:
0478:                        switch (opcode) {
0479:                        case Opcode.LDC:
0480:                            index = readUnsignedByte();
0481:                            break;
0482:                        case Opcode.LDC_W:
0483:                        case Opcode.LDC2_W:
0484:                            index = readUnsignedShort();
0485:                            break;
0486:                        default:
0487:                            index = 0;
0488:                            break;
0489:                        }
0490:
0491:                        try {
0492:                            ci = mCp.getConstant(index);
0493:                        } catch (IndexOutOfBoundsException e) {
0494:                            error(opcode, "Undefined constant at index: "
0495:                                    + index);
0496:                            break;
0497:                        }
0498:
0499:                        if (ci instanceof  ConstantStringInfo) {
0500:                            assembler.loadConstant(((ConstantStringInfo) ci)
0501:                                    .getValue());
0502:                        } else if (ci instanceof  ConstantIntegerInfo) {
0503:                            assembler.loadConstant(((ConstantIntegerInfo) ci)
0504:                                    .getValue());
0505:                        } else if (ci instanceof  ConstantLongInfo) {
0506:                            assembler.loadConstant(((ConstantLongInfo) ci)
0507:                                    .getValue());
0508:                        } else if (ci instanceof  ConstantFloatInfo) {
0509:                            assembler.loadConstant(((ConstantFloatInfo) ci)
0510:                                    .getValue());
0511:                        } else if (ci instanceof  ConstantDoubleInfo) {
0512:                            assembler.loadConstant(((ConstantDoubleInfo) ci)
0513:                                    .getValue());
0514:                        } else if (ci instanceof  ConstantClassInfo) {
0515:                            assembler.loadConstant(((ConstantClassInfo) ci)
0516:                                    .getType());
0517:                        } else {
0518:                            error(opcode, "Invalid constant type for load: "
0519:                                    + ci);
0520:                        }
0521:                        break;
0522:
0523:                    case Opcode.NEW:
0524:                        index = readUnsignedShort();
0525:                        try {
0526:                            ci = mCp.getConstant(index);
0527:                        } catch (IndexOutOfBoundsException e) {
0528:                            error(opcode, "Undefined constant at index: "
0529:                                    + index);
0530:                            break;
0531:                        }
0532:
0533:                        if (ci instanceof  ConstantClassInfo) {
0534:                            assembler.newObject(((ConstantClassInfo) ci)
0535:                                    .getType());
0536:                        } else {
0537:                            error(opcode, "Invalid constant type for new: "
0538:                                    + ci);
0539:                        }
0540:                        break;
0541:                    case Opcode.ANEWARRAY:
0542:                        index = readUnsignedShort();
0543:                        try {
0544:                            ci = mCp.getConstant(index);
0545:                        } catch (IndexOutOfBoundsException e) {
0546:                            error(opcode, "Undefined constant at index: "
0547:                                    + index);
0548:                            break;
0549:                        }
0550:
0551:                        if (ci instanceof  ConstantClassInfo) {
0552:                            type = ((ConstantClassInfo) ci).getType()
0553:                                    .toArrayType();
0554:                            assembler.newObject(type);
0555:                        } else {
0556:                            error(opcode, "Invalid constant type for new: "
0557:                                    + ci);
0558:                        }
0559:                        break;
0560:                    case Opcode.MULTIANEWARRAY:
0561:                        index = readUnsignedShort();
0562:                        try {
0563:                            ci = mCp.getConstant(index);
0564:                        } catch (IndexOutOfBoundsException e) {
0565:                            error(opcode, "Undefined constant at index: "
0566:                                    + index);
0567:                            break;
0568:                        }
0569:
0570:                        int dims = readUnsignedByte();
0571:                        if (ci instanceof  ConstantClassInfo) {
0572:                            type = ((ConstantClassInfo) ci).getType();
0573:                            assembler.newObject(type, dims);
0574:                        } else {
0575:                            error(opcode, "Invalid constant type for new: "
0576:                                    + ci);
0577:                        }
0578:                        break;
0579:
0580:                    case Opcode.CHECKCAST:
0581:                        index = readUnsignedShort();
0582:                        try {
0583:                            ci = mCp.getConstant(index);
0584:                        } catch (IndexOutOfBoundsException e) {
0585:                            error(opcode, "Undefined constant at index: "
0586:                                    + index);
0587:                            break;
0588:                        }
0589:
0590:                        if (ci instanceof  ConstantClassInfo) {
0591:                            assembler.checkCast(((ConstantClassInfo) ci)
0592:                                    .getType());
0593:                        } else {
0594:                            error(opcode,
0595:                                    "Invalid constant type for checkcast: "
0596:                                            + ci);
0597:                        }
0598:                        break;
0599:                    case Opcode.INSTANCEOF:
0600:                        index = readUnsignedShort();
0601:                        try {
0602:                            ci = mCp.getConstant(index);
0603:                        } catch (IndexOutOfBoundsException e) {
0604:                            error(opcode, "Undefined constant at index: "
0605:                                    + index);
0606:                            break;
0607:                        }
0608:
0609:                        if (ci instanceof  ConstantClassInfo) {
0610:                            assembler.instanceOf(((ConstantClassInfo) ci)
0611:                                    .getType());
0612:                        } else {
0613:                            error(opcode,
0614:                                    "Invalid constant type for instanceof: "
0615:                                            + ci);
0616:                        }
0617:                        break;
0618:
0619:                    case Opcode.GETSTATIC:
0620:                    case Opcode.PUTSTATIC:
0621:                    case Opcode.GETFIELD:
0622:                    case Opcode.PUTFIELD:
0623:                        index = readUnsignedShort();
0624:                        try {
0625:                            ci = mCp.getConstant(index);
0626:                        } catch (IndexOutOfBoundsException e) {
0627:                            error(opcode, "Undefined constant at index: "
0628:                                    + index);
0629:                            break;
0630:                        }
0631:
0632:                        if (!(ci instanceof  ConstantFieldInfo)) {
0633:                            error(opcode,
0634:                                    "Invalid constant type for field access: "
0635:                                            + ci);
0636:                            break;
0637:                        }
0638:
0639:                        ConstantFieldInfo field = (ConstantFieldInfo) ci;
0640:                        String className = field.getParentClass().getType()
0641:                                .getFullName();
0642:                        if (mEnclosingClassName.equals(className)) {
0643:                            className = null;
0644:                        }
0645:                        String fieldName = field.getNameAndType().getName();
0646:                        Descriptor desc = field.getNameAndType().getType();
0647:                        if (!(desc instanceof  TypeDesc)) {
0648:                            error(opcode,
0649:                                    "Invalid descriptor for field access: "
0650:                                            + desc);
0651:                            break;
0652:                        } else {
0653:                            type = (TypeDesc) desc;
0654:                        }
0655:
0656:                        // Implementation note: Although it may seem convenient if the
0657:                        // CodeAssembler had methods that accepted ConstantFieldInfo
0658:                        // objects as parameters, it would cause problems because
0659:                        // ConstantPools are not portable between ClassFiles.
0660:
0661:                        switch (opcode) {
0662:                        case Opcode.GETSTATIC:
0663:                            if (className == null) {
0664:                                assembler.loadStaticField(fieldName, type);
0665:                            } else {
0666:                                assembler.loadStaticField(className, fieldName,
0667:                                        type);
0668:                            }
0669:                            break;
0670:                        case Opcode.PUTSTATIC:
0671:                            if (className == null) {
0672:                                assembler.storeStaticField(fieldName, type);
0673:                            } else {
0674:                                assembler.storeStaticField(className,
0675:                                        fieldName, type);
0676:                            }
0677:                            break;
0678:                        case Opcode.GETFIELD:
0679:                            if (className == null) {
0680:                                assembler.loadField(fieldName, type);
0681:                            } else {
0682:                                assembler.loadField(className, fieldName, type);
0683:                            }
0684:                            break;
0685:                        case Opcode.PUTFIELD:
0686:                            if (className == null) {
0687:                                assembler.storeField(fieldName, type);
0688:                            } else {
0689:                                assembler
0690:                                        .storeField(className, fieldName, type);
0691:                            }
0692:                            break;
0693:                        }
0694:                        break;
0695:
0696:                    case Opcode.INVOKEVIRTUAL:
0697:                    case Opcode.INVOKESPECIAL:
0698:                    case Opcode.INVOKESTATIC:
0699:                    case Opcode.INVOKEINTERFACE:
0700:                        index = readUnsignedShort();
0701:                        try {
0702:                            ci = mCp.getConstant(index);
0703:                        } catch (IndexOutOfBoundsException e) {
0704:                            error(opcode, "Undefined constant at index: "
0705:                                    + index);
0706:                            break;
0707:                        }
0708:
0709:                        ConstantNameAndTypeInfo nameAndType;
0710:
0711:                        if (opcode == Opcode.INVOKEINTERFACE) {
0712:                            // Read and ignore nargs and padding byte.
0713:                            readShort();
0714:                            if (!(ci instanceof  ConstantInterfaceMethodInfo)) {
0715:                                error(opcode,
0716:                                        "Invalid constant type for method invocation: "
0717:                                                + ci);
0718:                                break;
0719:                            }
0720:                            ConstantInterfaceMethodInfo method = (ConstantInterfaceMethodInfo) ci;
0721:                            className = method.getParentClass().getType()
0722:                                    .getFullName();
0723:                            nameAndType = method.getNameAndType();
0724:                        } else {
0725:                            if (!(ci instanceof  ConstantMethodInfo)) {
0726:                                error(opcode,
0727:                                        "Invalid constant type for method invocation: "
0728:                                                + ci);
0729:                                break;
0730:                            }
0731:                            ConstantMethodInfo method = (ConstantMethodInfo) ci;
0732:                            className = method.getParentClass().getType()
0733:                                    .getFullName();
0734:                            if (mEnclosingClassName.equals(className)) {
0735:                                className = null;
0736:                            }
0737:                            nameAndType = method.getNameAndType();
0738:                        }
0739:
0740:                        String methodName = nameAndType.getName();
0741:                        desc = nameAndType.getType();
0742:                        if (!(desc instanceof  MethodDesc)) {
0743:                            error(opcode,
0744:                                    "Invalid descriptor for method invocation: "
0745:                                            + desc);
0746:                            break;
0747:                        }
0748:                        TypeDesc ret = ((MethodDesc) desc).getReturnType();
0749:                        if (ret == TypeDesc.VOID) {
0750:                            ret = null;
0751:                        }
0752:                        TypeDesc[] paramTypes = ((MethodDesc) desc)
0753:                                .getParameterTypes();
0754:                        if (paramTypes.length == 0) {
0755:                            paramTypes = null;
0756:                        }
0757:
0758:                        switch (opcode) {
0759:                        case Opcode.INVOKEVIRTUAL:
0760:                            if (className == null) {
0761:                                assembler.invokeVirtual(methodName, ret,
0762:                                        paramTypes);
0763:                            } else {
0764:                                assembler.invokeVirtual(className, methodName,
0765:                                        ret, paramTypes);
0766:                            }
0767:                            break;
0768:                        case Opcode.INVOKESPECIAL:
0769:                            if ("<init>".equals(methodName)) {
0770:                                if (className == null) {
0771:                                    assembler.invokeConstructor(paramTypes);
0772:                                } else {
0773:                                    if ("<init>".equals(mMethod.getName())
0774:                                            && className
0775:                                                    .equals(mSuperClassName)) {
0776:                                        assembler
0777:                                                .invokeSuperConstructor(paramTypes);
0778:                                    } else {
0779:                                        assembler.invokeConstructor(className,
0780:                                                paramTypes);
0781:                                    }
0782:                                }
0783:                            } else {
0784:                                if (className == null) {
0785:                                    assembler.invokePrivate(methodName, ret,
0786:                                            paramTypes);
0787:                                } else {
0788:                                    assembler.invokeSuper(className,
0789:                                            methodName, ret, paramTypes);
0790:                                }
0791:                            }
0792:                            break;
0793:                        case Opcode.INVOKESTATIC:
0794:                            if (className == null) {
0795:                                assembler.invokeStatic(methodName, ret,
0796:                                        paramTypes);
0797:                            } else {
0798:                                assembler.invokeStatic(className, methodName,
0799:                                        ret, paramTypes);
0800:                            }
0801:                            break;
0802:                        case Opcode.INVOKEINTERFACE:
0803:                            assembler.invokeInterface(className, methodName,
0804:                                    ret, paramTypes);
0805:                            break;
0806:                        }
0807:                        break;
0808:
0809:                    // End opcodes that load a constant from the constant pool.
0810:
0811:                    // Opcodes that load or store local variables...
0812:
0813:                    case Opcode.ILOAD:
0814:                    case Opcode.ISTORE:
0815:                    case Opcode.LLOAD:
0816:                    case Opcode.LSTORE:
0817:                    case Opcode.FLOAD:
0818:                    case Opcode.FSTORE:
0819:                    case Opcode.DLOAD:
0820:                    case Opcode.DSTORE:
0821:                    case Opcode.ALOAD:
0822:                    case Opcode.ASTORE:
0823:                    case Opcode.ILOAD_0:
0824:                    case Opcode.ISTORE_0:
0825:                    case Opcode.ILOAD_1:
0826:                    case Opcode.ISTORE_1:
0827:                    case Opcode.ILOAD_2:
0828:                    case Opcode.ISTORE_2:
0829:                    case Opcode.ILOAD_3:
0830:                    case Opcode.ISTORE_3:
0831:                    case Opcode.LLOAD_0:
0832:                    case Opcode.LSTORE_0:
0833:                    case Opcode.LLOAD_1:
0834:                    case Opcode.LSTORE_1:
0835:                    case Opcode.LLOAD_2:
0836:                    case Opcode.LSTORE_2:
0837:                    case Opcode.LLOAD_3:
0838:                    case Opcode.LSTORE_3:
0839:                    case Opcode.FLOAD_0:
0840:                    case Opcode.FSTORE_0:
0841:                    case Opcode.FLOAD_1:
0842:                    case Opcode.FSTORE_1:
0843:                    case Opcode.FLOAD_2:
0844:                    case Opcode.FSTORE_2:
0845:                    case Opcode.FLOAD_3:
0846:                    case Opcode.FSTORE_3:
0847:                    case Opcode.DLOAD_0:
0848:                    case Opcode.DSTORE_0:
0849:                    case Opcode.DLOAD_1:
0850:                    case Opcode.DSTORE_1:
0851:                    case Opcode.DLOAD_2:
0852:                    case Opcode.DSTORE_2:
0853:                    case Opcode.DLOAD_3:
0854:                    case Opcode.DSTORE_3:
0855:                    case Opcode.ALOAD_0:
0856:                    case Opcode.ASTORE_0:
0857:                    case Opcode.ALOAD_1:
0858:                    case Opcode.ASTORE_1:
0859:                    case Opcode.ALOAD_2:
0860:                    case Opcode.ASTORE_2:
0861:                    case Opcode.ALOAD_3:
0862:                    case Opcode.ASTORE_3:
0863:                        switch (opcode) {
0864:                        case Opcode.ILOAD:
0865:                        case Opcode.ISTORE:
0866:                            index = readUnsignedByte();
0867:                            type = TypeDesc.INT;
0868:                            break;
0869:                        case Opcode.LLOAD:
0870:                        case Opcode.LSTORE:
0871:                            index = readUnsignedByte();
0872:                            type = TypeDesc.LONG;
0873:                            break;
0874:                        case Opcode.FLOAD:
0875:                        case Opcode.FSTORE:
0876:                            index = readUnsignedByte();
0877:                            type = TypeDesc.FLOAT;
0878:                            break;
0879:                        case Opcode.DLOAD:
0880:                        case Opcode.DSTORE:
0881:                            index = readUnsignedByte();
0882:                            type = TypeDesc.DOUBLE;
0883:                            break;
0884:                        case Opcode.ALOAD:
0885:                        case Opcode.ASTORE:
0886:                            index = readUnsignedByte();
0887:                            type = TypeDesc.OBJECT;
0888:                            break;
0889:                        case Opcode.ILOAD_0:
0890:                        case Opcode.ISTORE_0:
0891:                            index = 0;
0892:                            type = TypeDesc.INT;
0893:                            break;
0894:                        case Opcode.ILOAD_1:
0895:                        case Opcode.ISTORE_1:
0896:                            index = 1;
0897:                            type = TypeDesc.INT;
0898:                            break;
0899:                        case Opcode.ILOAD_2:
0900:                        case Opcode.ISTORE_2:
0901:                            index = 2;
0902:                            type = TypeDesc.INT;
0903:                            break;
0904:                        case Opcode.ILOAD_3:
0905:                        case Opcode.ISTORE_3:
0906:                            index = 3;
0907:                            type = TypeDesc.INT;
0908:                            break;
0909:                        case Opcode.LLOAD_0:
0910:                        case Opcode.LSTORE_0:
0911:                            index = 0;
0912:                            type = TypeDesc.LONG;
0913:                            break;
0914:                        case Opcode.LLOAD_1:
0915:                        case Opcode.LSTORE_1:
0916:                            index = 1;
0917:                            type = TypeDesc.LONG;
0918:                            break;
0919:                        case Opcode.LLOAD_2:
0920:                        case Opcode.LSTORE_2:
0921:                            index = 2;
0922:                            type = TypeDesc.LONG;
0923:                            break;
0924:                        case Opcode.LLOAD_3:
0925:                        case Opcode.LSTORE_3:
0926:                            index = 3;
0927:                            type = TypeDesc.LONG;
0928:                            break;
0929:                        case Opcode.FLOAD_0:
0930:                        case Opcode.FSTORE_0:
0931:                            index = 0;
0932:                            type = TypeDesc.FLOAT;
0933:                            break;
0934:                        case Opcode.FLOAD_1:
0935:                        case Opcode.FSTORE_1:
0936:                            index = 1;
0937:                            type = TypeDesc.FLOAT;
0938:                            break;
0939:                        case Opcode.FLOAD_2:
0940:                        case Opcode.FSTORE_2:
0941:                            index = 2;
0942:                            type = TypeDesc.FLOAT;
0943:                            break;
0944:                        case Opcode.FLOAD_3:
0945:                        case Opcode.FSTORE_3:
0946:                            index = 3;
0947:                            type = TypeDesc.FLOAT;
0948:                            break;
0949:                        case Opcode.DLOAD_0:
0950:                        case Opcode.DSTORE_0:
0951:                            index = 0;
0952:                            type = TypeDesc.DOUBLE;
0953:                            break;
0954:                        case Opcode.DLOAD_1:
0955:                        case Opcode.DSTORE_1:
0956:                            index = 1;
0957:                            type = TypeDesc.DOUBLE;
0958:                            break;
0959:                        case Opcode.DLOAD_2:
0960:                        case Opcode.DSTORE_2:
0961:                            index = 2;
0962:                            type = TypeDesc.DOUBLE;
0963:                            break;
0964:                        case Opcode.DLOAD_3:
0965:                        case Opcode.DSTORE_3:
0966:                            index = 3;
0967:                            type = TypeDesc.DOUBLE;
0968:                            break;
0969:                        case Opcode.ALOAD_0:
0970:                        case Opcode.ASTORE_0:
0971:                            index = 0;
0972:                            type = TypeDesc.OBJECT;
0973:                            break;
0974:                        case Opcode.ALOAD_1:
0975:                        case Opcode.ASTORE_1:
0976:                            index = 1;
0977:                            type = TypeDesc.OBJECT;
0978:                            break;
0979:                        case Opcode.ALOAD_2:
0980:                        case Opcode.ASTORE_2:
0981:                            index = 2;
0982:                            type = TypeDesc.OBJECT;
0983:                            break;
0984:                        case Opcode.ALOAD_3:
0985:                        case Opcode.ASTORE_3:
0986:                            index = 3;
0987:                            type = TypeDesc.OBJECT;
0988:                            break;
0989:                        default:
0990:                            index = 0;
0991:                            type = null;
0992:                            break;
0993:                        }
0994:
0995:                        switch (opcode) {
0996:                        case Opcode.ILOAD:
0997:                        case Opcode.LLOAD:
0998:                        case Opcode.FLOAD:
0999:                        case Opcode.DLOAD:
1000:                        case Opcode.ALOAD:
1001:                        case Opcode.ILOAD_0:
1002:                        case Opcode.ILOAD_1:
1003:                        case Opcode.ILOAD_2:
1004:                        case Opcode.ILOAD_3:
1005:                        case Opcode.LLOAD_0:
1006:                        case Opcode.LLOAD_1:
1007:                        case Opcode.LLOAD_2:
1008:                        case Opcode.LLOAD_3:
1009:                        case Opcode.FLOAD_0:
1010:                        case Opcode.FLOAD_1:
1011:                        case Opcode.FLOAD_2:
1012:                        case Opcode.FLOAD_3:
1013:                        case Opcode.DLOAD_0:
1014:                        case Opcode.DLOAD_1:
1015:                        case Opcode.DLOAD_2:
1016:                        case Opcode.DLOAD_3:
1017:                        case Opcode.ALOAD_0:
1018:                        case Opcode.ALOAD_1:
1019:                        case Opcode.ALOAD_2:
1020:                        case Opcode.ALOAD_3:
1021:                            if (index == 0 && mHasThis) {
1022:                                assembler.loadThis();
1023:                            } else {
1024:                                assembler.loadLocal(getLocalVariable(index,
1025:                                        type));
1026:                            }
1027:                            break;
1028:                        case Opcode.ISTORE:
1029:                        case Opcode.LSTORE:
1030:                        case Opcode.FSTORE:
1031:                        case Opcode.DSTORE:
1032:                        case Opcode.ASTORE:
1033:                        case Opcode.ISTORE_0:
1034:                        case Opcode.ISTORE_1:
1035:                        case Opcode.ISTORE_2:
1036:                        case Opcode.ISTORE_3:
1037:                        case Opcode.LSTORE_0:
1038:                        case Opcode.LSTORE_1:
1039:                        case Opcode.LSTORE_2:
1040:                        case Opcode.LSTORE_3:
1041:                        case Opcode.FSTORE_0:
1042:                        case Opcode.FSTORE_1:
1043:                        case Opcode.FSTORE_2:
1044:                        case Opcode.FSTORE_3:
1045:                        case Opcode.DSTORE_0:
1046:                        case Opcode.DSTORE_1:
1047:                        case Opcode.DSTORE_2:
1048:                        case Opcode.DSTORE_3:
1049:                        case Opcode.ASTORE_0:
1050:                        case Opcode.ASTORE_1:
1051:                        case Opcode.ASTORE_2:
1052:                        case Opcode.ASTORE_3:
1053:                            if (index == 0 && mHasThis) {
1054:                                // The "this" reference just got blown away.
1055:                                mHasThis = false;
1056:                            }
1057:                            assembler.storeLocal(getLocalVariable(index, type));
1058:                            break;
1059:                        }
1060:                        break;
1061:
1062:                    case Opcode.RET:
1063:                        LocalVariable local = getLocalVariable(
1064:                                readUnsignedByte(), TypeDesc.OBJECT);
1065:                        assembler.ret(local);
1066:                        break;
1067:
1068:                    case Opcode.IINC:
1069:                        local = getLocalVariable(readUnsignedByte(),
1070:                                TypeDesc.INT);
1071:                        assembler.integerIncrement(local, readByte());
1072:                        break;
1073:
1074:                    // End opcodes that load or store local variables.
1075:
1076:                    // Opcodes that branch to another address.
1077:
1078:                    case Opcode.GOTO:
1079:                        loc = getLabel(mAddress + readShort());
1080:                        assembler.branch(loc);
1081:                        break;
1082:                    case Opcode.JSR:
1083:                        loc = getLabel(mAddress + readShort());
1084:                        assembler.jsr(loc);
1085:                        break;
1086:                    case Opcode.GOTO_W:
1087:                        loc = getLabel(mAddress + readInt());
1088:                        assembler.branch(loc);
1089:                        break;
1090:                    case Opcode.JSR_W:
1091:                        loc = getLabel(mAddress + readInt());
1092:                        assembler.jsr(loc);
1093:                        break;
1094:
1095:                    case Opcode.IFNULL:
1096:                        loc = getLabel(mAddress + readShort());
1097:                        assembler.ifNullBranch(loc, true);
1098:                        break;
1099:                    case Opcode.IFNONNULL:
1100:                        loc = getLabel(mAddress + readShort());
1101:                        assembler.ifNullBranch(loc, false);
1102:                        break;
1103:
1104:                    case Opcode.IF_ACMPEQ:
1105:                        loc = getLabel(mAddress + readShort());
1106:                        assembler.ifEqualBranch(loc, true);
1107:                        break;
1108:                    case Opcode.IF_ACMPNE:
1109:                        loc = getLabel(mAddress + readShort());
1110:                        assembler.ifEqualBranch(loc, false);
1111:                        break;
1112:
1113:                    case Opcode.IFEQ:
1114:                    case Opcode.IFNE:
1115:                    case Opcode.IFLT:
1116:                    case Opcode.IFGE:
1117:                    case Opcode.IFGT:
1118:                    case Opcode.IFLE:
1119:                        loc = getLabel(mAddress + readShort());
1120:                        String choice;
1121:                        switch (opcode) {
1122:                        case Opcode.IFEQ:
1123:                            choice = "==";
1124:                            break;
1125:                        case Opcode.IFNE:
1126:                            choice = "!=";
1127:                            break;
1128:                        case Opcode.IFLT:
1129:                            choice = "<";
1130:                            break;
1131:                        case Opcode.IFGE:
1132:                            choice = ">=";
1133:                            break;
1134:                        case Opcode.IFGT:
1135:                            choice = ">";
1136:                            break;
1137:                        case Opcode.IFLE:
1138:                            choice = "<=";
1139:                            break;
1140:                        default:
1141:                            choice = null;
1142:                            break;
1143:                        }
1144:                        assembler.ifZeroComparisonBranch(loc, choice);
1145:                        break;
1146:
1147:                    case Opcode.IF_ICMPEQ:
1148:                    case Opcode.IF_ICMPNE:
1149:                    case Opcode.IF_ICMPLT:
1150:                    case Opcode.IF_ICMPGE:
1151:                    case Opcode.IF_ICMPGT:
1152:                    case Opcode.IF_ICMPLE:
1153:                        loc = getLabel(mAddress + readShort());
1154:                        switch (opcode) {
1155:                        case Opcode.IF_ICMPEQ:
1156:                            choice = "==";
1157:                            break;
1158:                        case Opcode.IF_ICMPNE:
1159:                            choice = "!=";
1160:                            break;
1161:                        case Opcode.IF_ICMPLT:
1162:                            choice = "<";
1163:                            break;
1164:                        case Opcode.IF_ICMPGE:
1165:                            choice = ">=";
1166:                            break;
1167:                        case Opcode.IF_ICMPGT:
1168:                            choice = ">";
1169:                            break;
1170:                        case Opcode.IF_ICMPLE:
1171:                            choice = "<=";
1172:                            break;
1173:                        default:
1174:                            choice = null;
1175:                            break;
1176:                        }
1177:                        assembler.ifComparisonBranch(loc, choice);
1178:                        break;
1179:
1180:                    // End opcodes that branch to another address.
1181:
1182:                    // Miscellaneous opcodes...
1183:
1184:                    case Opcode.BIPUSH:
1185:                        assembler.loadConstant(readByte());
1186:                        break;
1187:                    case Opcode.SIPUSH:
1188:                        assembler.loadConstant(readShort());
1189:                        break;
1190:
1191:                    case Opcode.NEWARRAY:
1192:                        int atype = readByte();
1193:                        type = null;
1194:                        switch (atype) {
1195:                        case 4: // T_BOOLEAN
1196:                            type = TypeDesc.BOOLEAN;
1197:                            break;
1198:                        case 5: // T_CHAR
1199:                            type = TypeDesc.CHAR;
1200:                            break;
1201:                        case 6: // T_FLOAT
1202:                            type = TypeDesc.FLOAT;
1203:                            break;
1204:                        case 7: // T_DOUBLE
1205:                            type = TypeDesc.DOUBLE;
1206:                            break;
1207:                        case 8: // T_BYTE
1208:                            type = TypeDesc.BYTE;
1209:                            break;
1210:                        case 9: // T_SHORT
1211:                            type = TypeDesc.SHORT;
1212:                            break;
1213:                        case 10: // T_INT
1214:                            type = TypeDesc.INT;
1215:                            break;
1216:                        case 11: // T_LONG
1217:                            type = TypeDesc.LONG;
1218:                            break;
1219:                        }
1220:
1221:                        if (type == null) {
1222:                            error(opcode,
1223:                                    "Unknown primitive type for new array: "
1224:                                            + atype);
1225:                            break;
1226:                        }
1227:
1228:                        assembler.newObject(type.toArrayType());
1229:                        break;
1230:
1231:                    case Opcode.TABLESWITCH:
1232:                    case Opcode.LOOKUPSWITCH:
1233:                        int opcodeAddress = mAddress;
1234:                        // Read padding until address is 32 bit word aligned.
1235:                        while (((mAddress + 1) & 3) != 0) {
1236:                            ++mAddress;
1237:                        }
1238:                        Location defaultLocation = getLabel(opcodeAddress
1239:                                + readInt());
1240:                        int[] cases;
1241:                        Location[] locations;
1242:
1243:                        if (opcode == Opcode.TABLESWITCH) {
1244:                            int lowValue = readInt();
1245:                            int highValue = readInt();
1246:                            int caseCount = highValue - lowValue + 1;
1247:                            try {
1248:                                cases = new int[caseCount];
1249:                            } catch (NegativeArraySizeException e) {
1250:                                error(opcode,
1251:                                        "Negative case count for switch: "
1252:                                                + caseCount);
1253:                                break;
1254:                            }
1255:                            locations = new Location[caseCount];
1256:                            for (int i = 0; i < caseCount; i++) {
1257:                                cases[i] = lowValue + i;
1258:                                locations[i] = getLabel(opcodeAddress
1259:                                        + readInt());
1260:                            }
1261:                        } else {
1262:                            int caseCount = readInt();
1263:                            try {
1264:                                cases = new int[caseCount];
1265:                            } catch (NegativeArraySizeException e) {
1266:                                error(opcode,
1267:                                        "Negative case count for switch: "
1268:                                                + caseCount);
1269:                                break;
1270:                            }
1271:                            locations = new Location[caseCount];
1272:                            for (int i = 0; i < caseCount; i++) {
1273:                                cases[i] = readInt();
1274:                                locations[i] = getLabel(opcodeAddress
1275:                                        + readInt());
1276:                            }
1277:                        }
1278:
1279:                        assembler.switchBranch(cases, locations,
1280:                                defaultLocation);
1281:                        break;
1282:
1283:                    case Opcode.WIDE:
1284:                        opcode = mByteCodes[++mAddress];
1285:                        switch (opcode) {
1286:
1287:                        default:
1288:                            error(opcode, "Unknown wide instruction");
1289:                            break;
1290:
1291:                        case Opcode.ILOAD:
1292:                        case Opcode.ISTORE:
1293:                        case Opcode.LLOAD:
1294:                        case Opcode.LSTORE:
1295:                        case Opcode.FLOAD:
1296:                        case Opcode.FSTORE:
1297:                        case Opcode.DLOAD:
1298:                        case Opcode.DSTORE:
1299:                        case Opcode.ALOAD:
1300:                        case Opcode.ASTORE:
1301:
1302:                            switch (opcode) {
1303:                            case Opcode.ILOAD:
1304:                            case Opcode.ISTORE:
1305:                                type = TypeDesc.INT;
1306:                                break;
1307:                            case Opcode.LLOAD:
1308:                            case Opcode.LSTORE:
1309:                                type = TypeDesc.LONG;
1310:                                break;
1311:                            case Opcode.FLOAD:
1312:                            case Opcode.FSTORE:
1313:                                type = TypeDesc.FLOAT;
1314:                                break;
1315:                            case Opcode.DLOAD:
1316:                            case Opcode.DSTORE:
1317:                                type = TypeDesc.DOUBLE;
1318:                                break;
1319:                            case Opcode.ALOAD:
1320:                            case Opcode.ASTORE:
1321:                                type = TypeDesc.OBJECT;
1322:                                break;
1323:                            default:
1324:                                type = null;
1325:                                break;
1326:                            }
1327:
1328:                            index = readUnsignedShort();
1329:
1330:                            switch (opcode) {
1331:                            case Opcode.ILOAD:
1332:                            case Opcode.LLOAD:
1333:                            case Opcode.FLOAD:
1334:                            case Opcode.DLOAD:
1335:                            case Opcode.ALOAD:
1336:                                if (index == 0 && mHasThis) {
1337:                                    assembler.loadThis();
1338:                                } else {
1339:                                    assembler.loadLocal(getLocalVariable(index,
1340:                                            type));
1341:                                }
1342:                                break;
1343:                            case Opcode.ISTORE:
1344:                            case Opcode.LSTORE:
1345:                            case Opcode.FSTORE:
1346:                            case Opcode.DSTORE:
1347:                            case Opcode.ASTORE:
1348:                                if (index == 0 && mHasThis) {
1349:                                    // The "this" reference just got blown away.
1350:                                    mHasThis = false;
1351:                                }
1352:                                assembler.storeLocal(getLocalVariable(index,
1353:                                        type));
1354:                                break;
1355:                            }
1356:                            break;
1357:
1358:                        case Opcode.RET:
1359:                            local = getLocalVariable(readUnsignedShort(),
1360:                                    TypeDesc.OBJECT);
1361:                            assembler.ret(local);
1362:                            break;
1363:
1364:                        case Opcode.IINC:
1365:                            local = getLocalVariable(readUnsignedShort(),
1366:                                    TypeDesc.INT);
1367:                            assembler.integerIncrement(local, readShort());
1368:                            break;
1369:                        }
1370:
1371:                        break;
1372:                    } // end huge switch
1373:                } // end for loop
1374:            }
1375:
1376:            /**
1377:             * Invoked on disassembly errors. By default, this method does nothing.
1378:             */
1379:            protected void error(byte opcode, String message) {
1380:            }
1381:
1382:            private void gatherLabels() {
1383:                mLabels = new HashMap();
1384:                mCatchLocations = new HashMap(mExceptionHandlers.length * 2 + 1);
1385:                Integer labelKey;
1386:
1387:                // Gather labels for any exception handlers.
1388:                for (int i = mExceptionHandlers.length - 1; i >= 0; i--) {
1389:                    ExceptionHandler handler = mExceptionHandlers[i];
1390:                    labelKey = new Integer(handler.getStartLocation()
1391:                            .getLocation());
1392:                    mLabels.put(labelKey, labelKey);
1393:                    labelKey = new Integer(handler.getEndLocation()
1394:                            .getLocation());
1395:                    mLabels.put(labelKey, labelKey);
1396:                    labelKey = new Integer(handler.getCatchLocation()
1397:                            .getLocation());
1398:                    List list = (List) mCatchLocations.get(labelKey);
1399:                    if (list == null) {
1400:                        list = new ArrayList(2);
1401:                        mCatchLocations.put(labelKey, list);
1402:                    }
1403:                    list.add(handler);
1404:                }
1405:
1406:                // Now gather labels that occur within byte code.
1407:                for (mAddress = 0; mAddress < mByteCodes.length; mAddress++) {
1408:                    byte opcode = mByteCodes[mAddress];
1409:
1410:                    switch (opcode) {
1411:
1412:                    default:
1413:                        error(opcode, "Unknown opcode: " + (opcode & 0xff));
1414:                        break;
1415:
1416:                    // Opcodes that use labels.
1417:
1418:                    case Opcode.GOTO:
1419:                    case Opcode.JSR:
1420:                    case Opcode.IFNULL:
1421:                    case Opcode.IFNONNULL:
1422:                    case Opcode.IF_ACMPEQ:
1423:                    case Opcode.IF_ACMPNE:
1424:                    case Opcode.IFEQ:
1425:                    case Opcode.IFNE:
1426:                    case Opcode.IFLT:
1427:                    case Opcode.IFGE:
1428:                    case Opcode.IFGT:
1429:                    case Opcode.IFLE:
1430:                    case Opcode.IF_ICMPEQ:
1431:                    case Opcode.IF_ICMPNE:
1432:                    case Opcode.IF_ICMPLT:
1433:                    case Opcode.IF_ICMPGE:
1434:                    case Opcode.IF_ICMPGT:
1435:                    case Opcode.IF_ICMPLE:
1436:                        labelKey = new Integer(mAddress + readShort());
1437:                        mLabels.put(labelKey, labelKey);
1438:                        break;
1439:
1440:                    case Opcode.GOTO_W:
1441:                    case Opcode.JSR_W:
1442:                        labelKey = new Integer(mAddress + readInt());
1443:                        mLabels.put(labelKey, labelKey);
1444:                        break;
1445:
1446:                    case Opcode.TABLESWITCH:
1447:                    case Opcode.LOOKUPSWITCH:
1448:                        int opcodeAddress = mAddress;
1449:                        // Read padding until address is 32 bit word aligned.
1450:                        while (((mAddress + 1) & 3) != 0) {
1451:                            ++mAddress;
1452:                        }
1453:
1454:                        // Read the default location.
1455:                        labelKey = new Integer(opcodeAddress + readInt());
1456:                        mLabels.put(labelKey, labelKey);
1457:
1458:                        if (opcode == Opcode.TABLESWITCH) {
1459:                            int lowValue = readInt();
1460:                            int highValue = readInt();
1461:                            int caseCount = highValue - lowValue + 1;
1462:
1463:                            for (int i = 0; i < caseCount; i++) {
1464:                                // Read the branch location.
1465:                                labelKey = new Integer(opcodeAddress
1466:                                        + readInt());
1467:                                mLabels.put(labelKey, labelKey);
1468:                            }
1469:                        } else {
1470:                            int caseCount = readInt();
1471:
1472:                            for (int i = 0; i < caseCount; i++) {
1473:                                // Skip the case value.
1474:                                mAddress += 4;
1475:                                // Read the branch location.
1476:                                labelKey = new Integer(opcodeAddress
1477:                                        + readInt());
1478:                                mLabels.put(labelKey, labelKey);
1479:                            }
1480:                        }
1481:                        break;
1482:
1483:                    // All other operations are skipped. The amount to skip
1484:                    // depends on the operand size.
1485:
1486:                    // Opcodes with no operands...
1487:
1488:                    case Opcode.NOP:
1489:                    case Opcode.BREAKPOINT:
1490:                    case Opcode.ACONST_NULL:
1491:                    case Opcode.ICONST_M1:
1492:                    case Opcode.ICONST_0:
1493:                    case Opcode.ICONST_1:
1494:                    case Opcode.ICONST_2:
1495:                    case Opcode.ICONST_3:
1496:                    case Opcode.ICONST_4:
1497:                    case Opcode.ICONST_5:
1498:                    case Opcode.LCONST_0:
1499:                    case Opcode.LCONST_1:
1500:                    case Opcode.FCONST_0:
1501:                    case Opcode.FCONST_1:
1502:                    case Opcode.FCONST_2:
1503:                    case Opcode.DCONST_0:
1504:                    case Opcode.DCONST_1:
1505:                    case Opcode.POP:
1506:                    case Opcode.POP2:
1507:                    case Opcode.DUP:
1508:                    case Opcode.DUP_X1:
1509:                    case Opcode.DUP_X2:
1510:                    case Opcode.DUP2:
1511:                    case Opcode.DUP2_X1:
1512:                    case Opcode.DUP2_X2:
1513:                    case Opcode.SWAP:
1514:                    case Opcode.IADD:
1515:                    case Opcode.LADD:
1516:                    case Opcode.FADD:
1517:                    case Opcode.DADD:
1518:                    case Opcode.ISUB:
1519:                    case Opcode.LSUB:
1520:                    case Opcode.FSUB:
1521:                    case Opcode.DSUB:
1522:                    case Opcode.IMUL:
1523:                    case Opcode.LMUL:
1524:                    case Opcode.FMUL:
1525:                    case Opcode.DMUL:
1526:                    case Opcode.IDIV:
1527:                    case Opcode.LDIV:
1528:                    case Opcode.FDIV:
1529:                    case Opcode.DDIV:
1530:                    case Opcode.IREM:
1531:                    case Opcode.LREM:
1532:                    case Opcode.FREM:
1533:                    case Opcode.DREM:
1534:                    case Opcode.INEG:
1535:                    case Opcode.LNEG:
1536:                    case Opcode.FNEG:
1537:                    case Opcode.DNEG:
1538:                    case Opcode.ISHL:
1539:                    case Opcode.LSHL:
1540:                    case Opcode.ISHR:
1541:                    case Opcode.LSHR:
1542:                    case Opcode.IUSHR:
1543:                    case Opcode.LUSHR:
1544:                    case Opcode.IAND:
1545:                    case Opcode.LAND:
1546:                    case Opcode.IOR:
1547:                    case Opcode.LOR:
1548:                    case Opcode.IXOR:
1549:                    case Opcode.LXOR:
1550:                    case Opcode.FCMPL:
1551:                    case Opcode.DCMPL:
1552:                    case Opcode.FCMPG:
1553:                    case Opcode.DCMPG:
1554:                    case Opcode.LCMP:
1555:                    case Opcode.I2L:
1556:                    case Opcode.I2F:
1557:                    case Opcode.I2D:
1558:                    case Opcode.L2I:
1559:                    case Opcode.L2F:
1560:                    case Opcode.L2D:
1561:                    case Opcode.F2I:
1562:                    case Opcode.F2L:
1563:                    case Opcode.F2D:
1564:                    case Opcode.D2I:
1565:                    case Opcode.D2L:
1566:                    case Opcode.D2F:
1567:                    case Opcode.I2B:
1568:                    case Opcode.I2C:
1569:                    case Opcode.I2S:
1570:                    case Opcode.IRETURN:
1571:                    case Opcode.LRETURN:
1572:                    case Opcode.FRETURN:
1573:                    case Opcode.DRETURN:
1574:                    case Opcode.ARETURN:
1575:                    case Opcode.RETURN:
1576:                    case Opcode.IALOAD:
1577:                    case Opcode.LALOAD:
1578:                    case Opcode.FALOAD:
1579:                    case Opcode.DALOAD:
1580:                    case Opcode.AALOAD:
1581:                    case Opcode.BALOAD:
1582:                    case Opcode.CALOAD:
1583:                    case Opcode.SALOAD:
1584:                    case Opcode.IASTORE:
1585:                    case Opcode.LASTORE:
1586:                    case Opcode.FASTORE:
1587:                    case Opcode.DASTORE:
1588:                    case Opcode.AASTORE:
1589:                    case Opcode.BASTORE:
1590:                    case Opcode.CASTORE:
1591:                    case Opcode.SASTORE:
1592:                    case Opcode.ARRAYLENGTH:
1593:                    case Opcode.ATHROW:
1594:                    case Opcode.MONITORENTER:
1595:                    case Opcode.MONITOREXIT:
1596:                    case Opcode.ILOAD_0:
1597:                    case Opcode.ISTORE_0:
1598:                    case Opcode.ILOAD_1:
1599:                    case Opcode.ISTORE_1:
1600:                    case Opcode.ILOAD_2:
1601:                    case Opcode.ISTORE_2:
1602:                    case Opcode.ILOAD_3:
1603:                    case Opcode.ISTORE_3:
1604:                    case Opcode.LLOAD_0:
1605:                    case Opcode.LSTORE_0:
1606:                    case Opcode.LLOAD_1:
1607:                    case Opcode.LSTORE_1:
1608:                    case Opcode.LLOAD_2:
1609:                    case Opcode.LSTORE_2:
1610:                    case Opcode.LLOAD_3:
1611:                    case Opcode.LSTORE_3:
1612:                    case Opcode.FLOAD_0:
1613:                    case Opcode.FSTORE_0:
1614:                    case Opcode.FLOAD_1:
1615:                    case Opcode.FSTORE_1:
1616:                    case Opcode.FLOAD_2:
1617:                    case Opcode.FSTORE_2:
1618:                    case Opcode.FLOAD_3:
1619:                    case Opcode.FSTORE_3:
1620:                    case Opcode.DLOAD_0:
1621:                    case Opcode.DSTORE_0:
1622:                    case Opcode.DLOAD_1:
1623:                    case Opcode.DSTORE_1:
1624:                    case Opcode.DLOAD_2:
1625:                    case Opcode.DSTORE_2:
1626:                    case Opcode.DLOAD_3:
1627:                    case Opcode.DSTORE_3:
1628:                    case Opcode.ALOAD_0:
1629:                    case Opcode.ASTORE_0:
1630:                    case Opcode.ALOAD_1:
1631:                    case Opcode.ASTORE_1:
1632:                    case Opcode.ALOAD_2:
1633:                    case Opcode.ASTORE_2:
1634:                    case Opcode.ALOAD_3:
1635:                    case Opcode.ASTORE_3:
1636:                        break;
1637:
1638:                    // Opcodes with one operand byte...
1639:
1640:                    case Opcode.LDC:
1641:                    case Opcode.ILOAD:
1642:                    case Opcode.ISTORE:
1643:                    case Opcode.LLOAD:
1644:                    case Opcode.LSTORE:
1645:                    case Opcode.FLOAD:
1646:                    case Opcode.FSTORE:
1647:                    case Opcode.DLOAD:
1648:                    case Opcode.DSTORE:
1649:                    case Opcode.ALOAD:
1650:                    case Opcode.ASTORE:
1651:                    case Opcode.RET:
1652:                    case Opcode.BIPUSH:
1653:                    case Opcode.NEWARRAY:
1654:                        mAddress += 1;
1655:                        break;
1656:
1657:                    // Opcodes with two operand bytes...
1658:
1659:                    case Opcode.LDC_W:
1660:                    case Opcode.LDC2_W:
1661:                    case Opcode.NEW:
1662:                    case Opcode.ANEWARRAY:
1663:                    case Opcode.CHECKCAST:
1664:                    case Opcode.INSTANCEOF:
1665:                    case Opcode.GETSTATIC:
1666:                    case Opcode.PUTSTATIC:
1667:                    case Opcode.GETFIELD:
1668:                    case Opcode.PUTFIELD:
1669:                    case Opcode.INVOKEVIRTUAL:
1670:                    case Opcode.INVOKESPECIAL:
1671:                    case Opcode.INVOKESTATIC:
1672:                    case Opcode.SIPUSH:
1673:                    case Opcode.IINC:
1674:                        mAddress += 2;
1675:                        break;
1676:
1677:                    // Opcodes with three operand bytes...
1678:
1679:                    case Opcode.MULTIANEWARRAY:
1680:                        mAddress += 3;
1681:                        break;
1682:
1683:                    // Opcodes with four operand bytes...
1684:
1685:                    case Opcode.INVOKEINTERFACE:
1686:                        mAddress += 4;
1687:                        break;
1688:
1689:                    // Wide opcode has a variable sized operand.
1690:
1691:                    case Opcode.WIDE:
1692:                        opcode = mByteCodes[++mAddress];
1693:                        mAddress += 2;
1694:                        if (opcode == Opcode.IINC) {
1695:                            mAddress += 2;
1696:                        }
1697:                        break;
1698:                    } // end huge switch
1699:                } // end for loop
1700:            }
1701:
1702:            private int readByte() {
1703:                return mByteCodes[++mAddress];
1704:            }
1705:
1706:            private int readUnsignedByte() {
1707:                return mByteCodes[++mAddress] & 0xff;
1708:            }
1709:
1710:            private int readShort() {
1711:                return (mByteCodes[++mAddress] << 8)
1712:                        | (mByteCodes[++mAddress] & 0xff);
1713:            }
1714:
1715:            private int readUnsignedShort() {
1716:                return ((mByteCodes[++mAddress] & 0xff) << 8)
1717:                        | ((mByteCodes[++mAddress] & 0xff) << 0);
1718:            }
1719:
1720:            private int readInt() {
1721:                return (mByteCodes[++mAddress] << 24)
1722:                        | ((mByteCodes[++mAddress] & 0xff) << 16)
1723:                        | ((mByteCodes[++mAddress] & 0xff) << 8)
1724:                        | ((mByteCodes[++mAddress] & 0xff) << 0);
1725:            }
1726:
1727:            private LocalVariable getLocalVariable(final int index,
1728:                    final TypeDesc type) {
1729:                LocalVariable local;
1730:
1731:                if (index >= mLocals.size()) {
1732:                    mLocals.setSize(index + 1);
1733:                    local = mAssembler.createLocalVariable(null, type);
1734:                    mLocals.set(index, local);
1735:                    return local;
1736:                }
1737:
1738:                Object obj = mLocals.get(index);
1739:
1740:                if (obj == null) {
1741:                    local = mAssembler.createLocalVariable(null, type);
1742:                    mLocals.set(index, local);
1743:                    return local;
1744:                }
1745:
1746:                if (obj instanceof  LocalVariable) {
1747:                    local = (LocalVariable) obj;
1748:                    if (compatibleType(type, local.getType())) {
1749:                        return local;
1750:                    }
1751:                    // Variable takes on multiple types, so convert entry to a list.
1752:                    List locals = new ArrayList(4);
1753:                    locals.add(local);
1754:                    local = mAssembler.createLocalVariable(null, type);
1755:                    locals.add(local);
1756:                    mLocals.set(index, locals);
1757:                    return local;
1758:                }
1759:
1760:                List locals = (List) obj;
1761:                for (int i = locals.size(); --i >= 0;) {
1762:                    local = (LocalVariable) locals.get(i);
1763:                    if (compatibleType(type, local.getType())) {
1764:                        return local;
1765:                    }
1766:                }
1767:
1768:                local = mAssembler.createLocalVariable(null, type);
1769:                locals.add(local);
1770:                return local;
1771:            }
1772:
1773:            private boolean compatibleType(TypeDesc a, TypeDesc b) {
1774:                if (a == b || (!a.isPrimitive() && !b.isPrimitive())) {
1775:                    return true;
1776:                }
1777:                if (isIntType(a) && isIntType(b)) {
1778:                    return true;
1779:                }
1780:                return false;
1781:            }
1782:
1783:            private boolean isIntType(TypeDesc type) {
1784:                switch (type.getTypeCode()) {
1785:                case TypeDesc.INT_CODE:
1786:                case TypeDesc.BOOLEAN_CODE:
1787:                case TypeDesc.BYTE_CODE:
1788:                case TypeDesc.SHORT_CODE:
1789:                case TypeDesc.CHAR_CODE:
1790:                    return true;
1791:                }
1792:                return false;
1793:            }
1794:
1795:            private void locateLabel() {
1796:                Integer labelKey = new Integer(mAddress);
1797:                Object labelValue = mLabels.get(labelKey);
1798:                if (labelValue != null) {
1799:                    if (labelValue instanceof  Label) {
1800:                        ((Label) labelValue).setLocation();
1801:                    } else {
1802:                        labelValue = mAssembler.createLabel().setLocation();
1803:                        mLabels.put(labelKey, labelValue);
1804:                    }
1805:                }
1806:
1807:                List handlers = (List) mCatchLocations.get(labelKey);
1808:
1809:                if (handlers != null) {
1810:                    for (int i = 0; i < handlers.size(); i++) {
1811:                        ExceptionHandler handler = (ExceptionHandler) handlers
1812:                                .get(i);
1813:                        Label start = getLabel(handler.getStartLocation()
1814:                                .getLocation());
1815:                        Label end = getLabel(handler.getEndLocation()
1816:                                .getLocation());
1817:                        String catchClassName;
1818:                        if (handler.getCatchType() == null) {
1819:                            catchClassName = null;
1820:                        } else {
1821:                            catchClassName = handler.getCatchType().getType()
1822:                                    .getFullName();
1823:                        }
1824:                        mAssembler.exceptionHandler(start, end, catchClassName);
1825:                    }
1826:                }
1827:            }
1828:
1829:            private Label getLabel(int address) {
1830:                Integer labelKey = new Integer(address);
1831:                Object labelValue = mLabels.get(labelKey);
1832:                // labelValue will never be null unless gatherLabels is broken.
1833:                if (!(labelValue instanceof  Label)) {
1834:                    labelValue = mAssembler.createLabel();
1835:                    mLabels.put(labelKey, labelValue);
1836:                }
1837:                return (Label) labelValue;
1838:            }
1839:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.