Source Code Cross Referenced for CFG.java in  » Code-Analyzer » soot » soot » coffi » 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 » Code Analyzer » soot » soot.coffi 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* Soot - a J*va Optimization Framework
0002:         * Copyright (C) 1997 Clark Verbrugge
0003:         *
0004:         * This library is free software; you can redistribute it and/or
0005:         * modify it under the terms of the GNU Lesser General Public
0006:         * License as published by the Free Software Foundation; either
0007:         * version 2.1 of the License, or (at your option) any later version.
0008:         *
0009:         * This library is distributed in the hope that it will be useful,
0010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012:         * Lesser General Public License for more details.
0013:         *
0014:         * You should have received a copy of the GNU Lesser General Public
0015:         * License along with this library; if not, write to the
0016:         * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
0017:         * Boston, MA 02111-1307, USA.
0018:         */
0019:
0020:        /*
0021:         * Modified by the Sable Research Group and others 1997-1999.  
0022:         * See the 'credits' file distributed with Soot for the complete list of
0023:         * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
0024:         */
0025:
0026:        package soot.coffi;
0027:
0028:        import soot.options.*;
0029:
0030:        import java.util.*;
0031:
0032:        import soot.*;
0033:        import soot.jimple.*;
0034:        import soot.util.*;
0035:        import soot.tagkit.*;
0036:
0037:        /** A Control Flow Graph.
0038:         * @author Clark Verbrugge
0039:         */
0040:        public class CFG {
0041:
0042:            /** Method for which this is a control flow graph.
0043:             * @see method_info
0044:             */
0045:            private method_info method;
0046:            /** Ordered list of BasicBlocks comprising the code of this CFG.
0047:             */
0048:            BasicBlock cfg;
0049:
0050:            Chain units;
0051:            JimpleBody listBody;
0052:
0053:            Map<Instruction, Stmt> instructionToFirstStmt;
0054:            Map<Instruction, Stmt> instructionToLastStmt;
0055:            SootMethod jmethod;
0056:            Scene cm;
0057:
0058:            Instruction firstInstruction;
0059:            Instruction lastInstruction;
0060:
0061:            private Instruction sentinel;
0062:            private Hashtable<Instruction, BasicBlock> h2bb, t2bb;
0063:
0064:            /** Constructs a new control flow graph for the given method.
0065:             * @param m the method in question.
0066:             * @see method_info
0067:             */
0068:            public CFG(method_info m) {
0069:                this .method = m;
0070:
0071:                this .sentinel = new Instruction_Nop();
0072:                this .sentinel.next = m.instructions;
0073:                m.instructions.prev = this .sentinel;
0074:
0075:                //	printInstructions();
0076:                //	printExceptionTable();
0077:
0078:                eliminateJsrRets();
0079:
0080:                //	printInstructions();
0081:                //	printExceptionTable();
0082:
0083:                buildBBCFG();
0084:
0085:                // printBBs();
0086:                // printBBCFGSucc();
0087:
0088:                cfg.beginCode = true;
0089:
0090:                m.cfg = this ;
0091:
0092:                if (cfg != null)
0093:                    firstInstruction = cfg.head;
0094:                else
0095:                    firstInstruction = null;
0096:
0097:                // calculate complexity metrics
0098:                if (soot.jbco.Main.metrics)
0099:                    complexity();
0100:
0101:                /*	
0102:                if (m.code_attr != null)
0103:                {
0104:                    for (int i=0; i<m.code_attr.attributes.length; i++)
0105:                    {
0106:                	if (m.code_attr.attributes[i] 
0107:                	    instanceof LineNumberTable_attribute)
0108:                	{
0109:                	    G.v().out.print(m.code_attr.attributes[i]);
0110:                	}
0111:                    }
0112:                }
0113:                 */
0114:            }
0115:
0116:            public static HashMap<SootMethod, int[]> methodsToVEM = new HashMap<SootMethod, int[]>();
0117:
0118:            private void complexity() {
0119:                // ignore all non-app classes
0120:                if (!method.jmethod.getDeclaringClass().isApplicationClass())
0121:                    return;
0122:
0123:                BasicBlock b = this .cfg;
0124:                HashMap<BasicBlock, Integer> block2exc = new HashMap<BasicBlock, Integer>();
0125:                int tmp, nodes = 0, edges = 0, highest = 0;
0126:
0127:                while (b != null) {
0128:                    tmp = 0;
0129:                    for (exception_table_entry element : method.code_attr.exception_table) {
0130:                        Instruction start = element.start_inst;
0131:                        Instruction end = element.start_inst;
0132:                        if ((start.label >= b.head.label && start.label <= b.tail.label)
0133:                                || (end.label > b.head.label && (b.tail.next == null || end.label <= b.tail.next.label)))
0134:                            tmp++;
0135:                    }
0136:                    block2exc.put(b, new Integer(tmp));
0137:                    b = b.next;
0138:                }
0139:
0140:                b = this .cfg;
0141:                while (b != null) {
0142:                    nodes++;
0143:                    tmp = b.succ.size() + block2exc.get(b).intValue();
0144:
0145:                    // exceptions are not counted in succs and preds so we need to do so manually
0146:                    int deg = b.pred.size() + tmp + (b.beginException ? 1 : 0);
0147:                    if (deg > highest)
0148:                        highest = deg;
0149:                    edges += tmp;
0150:                    b = b.next;
0151:                }
0152:                methodsToVEM.put(method.jmethod, new int[] { nodes, edges,
0153:                        highest });
0154:            }
0155:
0156:            // Constructs the actual control flow graph. Assumes the hash table
0157:            // currently associates leaders with BasicBlocks, this function
0158:            // builds the next[] and prev[] pointer arrays.
0159:            private void buildBBCFG() {
0160:                Object branches[];
0161:                Code_attribute ca = method.locate_code_attribute();
0162:
0163:                {
0164:                    h2bb = new Hashtable<Instruction, BasicBlock>(100, 25);
0165:                    t2bb = new Hashtable<Instruction, BasicBlock>(100, 25);
0166:
0167:                    Instruction insn = this .sentinel.next;
0168:                    BasicBlock blast = null;
0169:                    if (insn != null) {
0170:                        Instruction tail = buildBasicBlock(insn);
0171:                        cfg = new BasicBlock(insn, tail);
0172:                        h2bb.put(insn, cfg);
0173:                        t2bb.put(tail, cfg);
0174:                        insn = tail.next;
0175:                        blast = cfg;
0176:                    }
0177:
0178:                    while (insn != null) {
0179:                        Instruction tail = buildBasicBlock(insn);
0180:                        BasicBlock block = new BasicBlock(insn, tail);
0181:                        blast.next = block;
0182:                        blast = block;
0183:                        h2bb.put(insn, block);
0184:                        t2bb.put(tail, block);
0185:                        insn = tail.next;
0186:                    }
0187:                }
0188:
0189:                BasicBlock block = cfg;
0190:
0191:                while (block != null) {
0192:                    Instruction insn = block.tail;
0193:
0194:                    if (insn.branches) {
0195:                        if (insn instanceof  Instruction_Athrow) {
0196:                            // see how many targets it can reach.  Note that this is a
0197:                            // subset of the exception_table.
0198:                            HashSet<Instruction> ethandlers = new HashSet<Instruction>();
0199:
0200:                            // not quite a subset---could also be that control 
0201:                            // exits this method, so start icount at 1
0202:                            for (int i = 0; i < ca.exception_table_length; i++) {
0203:                                exception_table_entry etentry = ca.exception_table[i];
0204:
0205:                                if (insn.label >= etentry.start_inst.label
0206:                                        && (etentry.end_inst == null || insn.label < etentry.end_inst.label)) {
0207:                                    ethandlers.add(etentry.handler_inst);
0208:                                }
0209:                            }
0210:
0211:                            branches = ethandlers.toArray();
0212:                        } else {
0213:                            branches = insn.branchpoints(insn.next);
0214:                        }
0215:
0216:                        if (branches != null) {
0217:                            block.succ.ensureCapacity(block.succ.size()
0218:                                    + branches.length);
0219:
0220:                            for (Object element : branches) {
0221:                                if (element != null) {
0222:                                    BasicBlock bb = h2bb.get(element);
0223:
0224:                                    if (bb == null) {
0225:                                        G.v().out.println("Warning: "
0226:                                                + "target of a branch is null");
0227:                                        G.v().out.println(insn);
0228:                                    } else {
0229:                                        block.succ.addElement(bb);
0230:                                        bb.pred.addElement(block);
0231:                                    }
0232:                                }
0233:                            }
0234:                        }
0235:                    } else if (block.next != null) { // BB ended not with a branch, so just go to next
0236:                        block.succ.addElement(block.next);
0237:                        block.next.pred.addElement(block);
0238:                    }
0239:                    block = block.next;
0240:                }
0241:
0242:                // One final step, run through exception handlers and mark which
0243:                // basic blocks begin their code
0244:                for (int i = 0; i < ca.exception_table_length; i++) {
0245:                    BasicBlock bb = h2bb
0246:                            .get(ca.exception_table[i].handler_inst);
0247:                    if (bb == null) {
0248:                        G.v().out.println("Warning: No basic block found for"
0249:                                + " start of exception handler code.");
0250:                    } else {
0251:                        bb.beginException = true;
0252:                        ca.exception_table[i].b = bb;
0253:                    }
0254:                }
0255:            }
0256:
0257:            /* given the list of instructions head, this pulls off the front
0258:             * basic block, terminates it with a null, and returns the next
0259:             * instruction after.
0260:             */
0261:            private static Instruction buildBasicBlock(Instruction head) {
0262:                Instruction insn, next;
0263:                insn = head;
0264:                next = insn.next;
0265:
0266:                if (next == null)
0267:                    return insn;
0268:
0269:                do {
0270:                    if (insn.branches || next.labelled)
0271:                        break;
0272:                    else {
0273:                        insn = next;
0274:                        next = insn.next;
0275:                    }
0276:                } while (next != null);
0277:
0278:                return insn;
0279:            }
0280:
0281:            /* We only handle simple cases. */
0282:            Map<Instruction, Instruction> jsr2astore = new HashMap<Instruction, Instruction>();
0283:            Map<Instruction, Instruction> astore2ret = new HashMap<Instruction, Instruction>();
0284:
0285:            LinkedList<Instruction> jsrorder = new LinkedList<Instruction>();
0286:
0287:            /* Eliminate subroutines ( JSR/RET instructions ) by inlining the 
0288:               routine bodies. */
0289:            private boolean eliminateJsrRets() {
0290:                Instruction insn = this .sentinel;
0291:
0292:                // find the last instruction, for copying blocks.
0293:                while (insn.next != null) {
0294:                    insn = insn.next;
0295:                }
0296:                this .lastInstruction = insn;
0297:
0298:                HashMap<Instruction, Instruction> todoBlocks = new HashMap<Instruction, Instruction>();
0299:                todoBlocks.put(this .sentinel.next, this .lastInstruction);
0300:                LinkedList<Instruction> todoList = new LinkedList<Instruction>();
0301:                todoList.add(this .sentinel.next);
0302:
0303:                while (!todoList.isEmpty()) {
0304:                    Instruction firstInsn = todoList.removeFirst();
0305:                    Instruction lastInsn = todoBlocks.get(firstInsn);
0306:
0307:                    jsrorder.clear();
0308:                    jsr2astore.clear();
0309:                    astore2ret.clear();
0310:
0311:                    if (findOutmostJsrs(firstInsn, lastInsn)) {
0312:                        HashMap<Instruction, Instruction> newblocks = inliningJsrTargets();
0313:                        todoBlocks.putAll(newblocks);
0314:                        todoList.addAll(newblocks.keySet());
0315:                    }
0316:                }
0317:
0318:                /* patch exception table and others.*/
0319:                {
0320:                    method.instructions = this .sentinel.next;
0321:
0322:                    adjustExceptionTable();
0323:                    adjustLineNumberTable();
0324:                    adjustBranchTargets();
0325:                }
0326:
0327:                // we should prune the code and exception table here.
0328:                // remove any exception handler whose region is in a jsr/ret block.
0329:                // pruneExceptionTable();
0330:
0331:                return true;
0332:            }
0333:
0334:            // find outmost jsr/ret pairs in a code area, all information is
0335:            // saved in jsr2astore, and astore2ret
0336:            // start : start instruction, inclusively.
0337:            // end   : the last instruction, inclusively.
0338:            // return the last instruction encounted ( before end )
0339:            // the caller cleans jsr2astore, astore2ret
0340:            private boolean findOutmostJsrs(Instruction start, Instruction end) {
0341:                // use to put innerJsrs.
0342:                HashSet<Instruction> innerJsrs = new HashSet<Instruction>();
0343:                boolean unusual = false;
0344:
0345:                Instruction insn = start;
0346:                do {
0347:                    if (insn instanceof  Instruction_Jsr
0348:                            || insn instanceof  Instruction_Jsr_w) {
0349:                        if (innerJsrs.contains(insn)) {
0350:                            // skip it
0351:                            insn = insn.next;
0352:                            continue;
0353:                        }
0354:
0355:                        Instruction astore = ((Instruction_branch) insn).target;
0356:                        if (!(astore instanceof  Interface_Astore)) {
0357:                            unusual = true;
0358:                            break;
0359:                        }
0360:
0361:                        Instruction ret = findMatchingRet(astore, insn,
0362:                                innerJsrs);
0363:
0364:                        /*
0365:                        if (ret == null)
0366:                        {
0367:                            unusual = true;
0368:                            break;
0369:                        }
0370:                         */
0371:
0372:                        jsrorder.addLast(insn);
0373:                        jsr2astore.put(insn, astore);
0374:                        astore2ret.put(astore, ret);
0375:                    }
0376:
0377:                    insn = insn.next;
0378:
0379:                } while (insn != end.next);
0380:
0381:                if (unusual) {
0382:                    G.v().out.println("Sorry, I cannot handle this method.");
0383:                    return false;
0384:                }
0385:
0386:                return true;
0387:            }
0388:
0389:            private Instruction findMatchingRet(Instruction astore,
0390:                    Instruction jsr, HashSet<Instruction> innerJsrs) {
0391:                int astorenum = ((Interface_Astore) astore).getLocalNumber();
0392:
0393:                Instruction insn = astore.next;
0394:                while (insn != null) {
0395:                    if (insn instanceof  Instruction_Ret
0396:                            || insn instanceof  Instruction_Ret_w) {
0397:                        int retnum = ((Interface_OneIntArg) insn).getIntArg();
0398:                        if (astorenum == retnum)
0399:                            return insn;
0400:                    } else
0401:                    /* adjust the jsr inlining order. */
0402:                    if (insn instanceof  Instruction_Jsr
0403:                            || insn instanceof  Instruction_Jsr_w) {
0404:                        innerJsrs.add(insn);
0405:                    }
0406:
0407:                    insn = insn.next;
0408:                }
0409:
0410:                return null;
0411:            }
0412:
0413:            // make copies of jsr/ret blocks
0414:            // return new blocks
0415:            private HashMap<Instruction, Instruction> inliningJsrTargets() {
0416:                /*
0417:                for (int i=0, n=jsrorder.size(); i<n; i++) {
0418:                    Instruction jsr    = (Instruction)jsrorder.get(i);
0419:                    Instruction astore = (Instruction)jsr2astore.get(jsr);
0420:                    Instruction ret    = (Instruction)astore2ret.get(astore);
0421:                    G.v().out.println("jsr"+jsr.label+"\t"
0422:                		       +"as"+astore.label+"\t"
0423:                		       +"ret"+ret.label);
0424:                }
0425:                 */
0426:                HashMap<Instruction, Instruction> newblocks = new HashMap<Instruction, Instruction>();
0427:
0428:                while (!jsrorder.isEmpty()) {
0429:                    Instruction jsr = jsrorder.removeFirst();
0430:                    Instruction astore = jsr2astore.get(jsr);
0431:
0432:                    Instruction ret = astore2ret.get(astore);
0433:
0434:                    // make a copy of the code, append to the last instruction.     
0435:                    Instruction newhead = makeCopyOf(astore, ret, jsr.next);
0436:
0437:                    // jsr is replaced by goto newhead
0438:                    // astore has been removed
0439:                    // ret is replaced by goto jsr.next
0440:                    Instruction_Goto togo = new Instruction_Goto();
0441:                    togo.target = newhead;
0442:                    newhead.labelled = true;
0443:                    togo.label = jsr.label;
0444:                    togo.labelled = jsr.labelled;
0445:                    togo.prev = jsr.prev;
0446:                    togo.next = jsr.next;
0447:                    togo.prev.next = togo;
0448:                    togo.next.prev = togo;
0449:
0450:                    replacedInsns.put(jsr, togo);
0451:
0452:                    // just quick hack
0453:                    if (ret != null) {
0454:                        newblocks.put(newhead, this .lastInstruction);
0455:                    }
0456:                }
0457:
0458:                return newblocks;
0459:            }
0460:
0461:            /* make a copy of code between from and to exclusively, 
0462:             * fixup targets of branch instructions in the code.
0463:             */
0464:            private Instruction makeCopyOf(Instruction astore, Instruction ret,
0465:                    Instruction target) {
0466:                // do a quick hacker for ret == null
0467:                if (ret == null) {
0468:                    return astore.next;
0469:                }
0470:
0471:                Instruction last = this .lastInstruction;
0472:                Instruction headbefore = last;
0473:
0474:                int curlabel = this .lastInstruction.label;
0475:
0476:                // mapping from original instructions to new instructions.
0477:                HashMap<Instruction, Instruction> insnmap = new HashMap<Instruction, Instruction>();
0478:                Instruction insn = astore.next;
0479:
0480:                while (insn != ret && insn != null) {
0481:                    try {
0482:                        Instruction newone = (Instruction) insn.clone();
0483:
0484:                        newone.label = ++curlabel;
0485:                        newone.prev = last;
0486:                        last.next = newone;
0487:                        last = newone;
0488:
0489:                        insnmap.put(insn, newone);
0490:                    } catch (CloneNotSupportedException e) {
0491:                        G.v().out.println("Error !");
0492:                    }
0493:                    insn = insn.next;
0494:                }
0495:
0496:                // replace ret by a goto
0497:                Instruction_Goto togo = new Instruction_Goto();
0498:                togo.target = target;
0499:                target.labelled = true;
0500:                togo.label = ++curlabel;
0501:                last.next = togo;
0502:                togo.prev = last;
0503:                last = togo;
0504:
0505:                this .lastInstruction = last;
0506:
0507:                // The ret instruction is removed, 
0508:                insnmap.put(astore, headbefore.next);
0509:                insnmap.put(ret, togo);
0510:
0511:                // fixup targets in new instruction (only in the scope of 
0512:                //  new instructions).
0513:                // do not forget set target labelled as TRUE
0514:                insn = headbefore.next;
0515:                while (insn != last) {
0516:                    if (insn instanceof  Instruction_branch) {
0517:                        Instruction oldtgt = ((Instruction_branch) insn).target;
0518:                        Instruction newtgt = insnmap.get(oldtgt);
0519:                        if (newtgt != null) {
0520:                            ((Instruction_branch) insn).target = newtgt;
0521:                            newtgt.labelled = true;
0522:                        }
0523:                    } else if (insn instanceof  Instruction_Lookupswitch) {
0524:                        Instruction_Lookupswitch switchinsn = (Instruction_Lookupswitch) insn;
0525:
0526:                        Instruction newdefault = insnmap
0527:                                .get(switchinsn.default_inst);
0528:                        if (newdefault != null) {
0529:                            switchinsn.default_inst = newdefault;
0530:                            newdefault.labelled = true;
0531:                        }
0532:
0533:                        for (int i = 0; i < switchinsn.match_insts.length; i++) {
0534:                            Instruction newtgt = insnmap
0535:                                    .get(switchinsn.match_insts[i]);
0536:                            if (newtgt != null) {
0537:                                switchinsn.match_insts[i] = newtgt;
0538:                                newtgt.labelled = true;
0539:                            }
0540:                        }
0541:                    } else if (insn instanceof  Instruction_Tableswitch) {
0542:                        Instruction_Tableswitch switchinsn = (Instruction_Tableswitch) insn;
0543:
0544:                        Instruction newdefault = insnmap
0545:                                .get(switchinsn.default_inst);
0546:                        if (newdefault != null) {
0547:                            switchinsn.default_inst = newdefault;
0548:                            newdefault.labelled = true;
0549:                        }
0550:
0551:                        for (int i = 0; i < switchinsn.jump_insts.length; i++) {
0552:                            Instruction newtgt = insnmap
0553:                                    .get(switchinsn.jump_insts[i]);
0554:                            if (newtgt != null) {
0555:                                switchinsn.jump_insts[i] = newtgt;
0556:                                newtgt.labelled = true;
0557:                            }
0558:                        }
0559:                    }
0560:
0561:                    insn = insn.next;
0562:                }
0563:
0564:                // do we need to copy a new exception table entry? 
0565:                // new exception table has new exception range, 
0566:                // and the new exception handler.
0567:                {
0568:                    Code_attribute ca = method.locate_code_attribute();
0569:
0570:                    LinkedList<exception_table_entry> newentries = new LinkedList<exception_table_entry>();
0571:
0572:                    int orig_start_of_subr = astore.next.originalIndex; // inclusive
0573:                    int orig_end_of_subr = ret.originalIndex; // again, inclusive
0574:
0575:                    for (int i = 0; i < ca.exception_table_length; i++) {
0576:                        exception_table_entry etentry = ca.exception_table[i];
0577:
0578:                        int orig_start_of_trap = etentry.start_pc; // inclusive
0579:                        int orig_end_of_trap = etentry.end_pc; // exclusive
0580:                        if (orig_start_of_trap < orig_end_of_subr
0581:                                && orig_end_of_trap > orig_start_of_subr) {
0582:                            // At least a portion of the cloned subroutine is trapped.
0583:                            exception_table_entry newone = new exception_table_entry();
0584:                            if (orig_start_of_trap <= orig_start_of_subr) {
0585:                                newone.start_inst = headbefore.next;
0586:                            } else {
0587:                                newone.start_inst = insnmap
0588:                                        .get(etentry.start_inst);
0589:                            }
0590:                            if (orig_end_of_trap > orig_end_of_subr) {
0591:                                newone.end_inst = null; // Representing the insn after
0592:                                // the last instruction in the
0593:                                // subr; we need to fix it if
0594:                                // we inline another subr.
0595:                            } else {
0596:                                newone.end_inst = insnmap.get(etentry.end_inst);
0597:                            }
0598:
0599:                            newone.handler_inst = insnmap
0600:                                    .get(etentry.handler_inst);
0601:                            if (newone.handler_inst == null)
0602:                                newone.handler_inst = etentry.handler_inst;
0603:
0604:                            // We can leave newone.start_pc == 0 and newone.end_pc == 0.
0605:                            // since that cannot overlap the range of any other
0606:                            // subroutines that get inlined later.
0607:
0608:                            newentries.add(newone);
0609:                        }
0610:                        // Finally, fix up the old entry if its protected area
0611:                        // ran to the end of the method we have just lengthened:
0612:                        // patch its end marker to be the first
0613:                        // instruction in the subroutine we've just inlined.
0614:                        if (etentry.end_inst == null) {
0615:                            etentry.end_inst = headbefore.next;
0616:                        }
0617:                    }
0618:
0619:                    if (newentries.size() > 0) {
0620:                        ca.exception_table_length += newentries.size();
0621:                        exception_table_entry[] newtable = new exception_table_entry[ca.exception_table_length];
0622:                        System.arraycopy(ca.exception_table, 0, newtable, 0,
0623:                                ca.exception_table.length);
0624:                        for (int i = 0, j = ca.exception_table.length; i < newentries
0625:                                .size(); i++, j++) {
0626:                            newtable[j] = newentries.get(i);
0627:                        }
0628:
0629:                        ca.exception_table = newtable;
0630:                    }
0631:                }
0632:
0633:                return headbefore.next;
0634:            }
0635:
0636:            /* if a jsr/astore/ret is replaced by some other instruction, it will be put on this table. */
0637:            private final Hashtable<Instruction, Instruction_Goto> replacedInsns = new Hashtable<Instruction, Instruction_Goto>();
0638:
0639:            /* do not forget set the target labelled as TRUE.*/
0640:            private void adjustBranchTargets() {
0641:                Instruction insn = this .sentinel.next;
0642:                while (insn != null) {
0643:                    if (insn instanceof  Instruction_branch) {
0644:                        Instruction_branch binsn = (Instruction_branch) insn;
0645:                        Instruction newtgt = replacedInsns.get(binsn.target);
0646:                        if (newtgt != null) {
0647:                            binsn.target = newtgt;
0648:                            newtgt.labelled = true;
0649:                        }
0650:                    } else if (insn instanceof  Instruction_Lookupswitch) {
0651:                        Instruction_Lookupswitch switchinsn = (Instruction_Lookupswitch) insn;
0652:
0653:                        Instruction newdefault = replacedInsns
0654:                                .get(switchinsn.default_inst);
0655:                        if (newdefault != null) {
0656:                            switchinsn.default_inst = newdefault;
0657:                            newdefault.labelled = true;
0658:                        }
0659:
0660:                        for (int i = 0; i < switchinsn.npairs; i++) {
0661:                            Instruction newtgt = replacedInsns
0662:                                    .get(switchinsn.match_insts[i]);
0663:                            if (newtgt != null) {
0664:                                switchinsn.match_insts[i] = newtgt;
0665:                                newtgt.labelled = true;
0666:                            }
0667:                        }
0668:                    } else if (insn instanceof  Instruction_Tableswitch) {
0669:                        Instruction_Tableswitch switchinsn = (Instruction_Tableswitch) insn;
0670:
0671:                        Instruction newdefault = replacedInsns
0672:                                .get(switchinsn.default_inst);
0673:                        if (newdefault != null) {
0674:                            switchinsn.default_inst = newdefault;
0675:                            newdefault.labelled = true;
0676:                        }
0677:
0678:                        for (int i = 0; i <= switchinsn.high - switchinsn.low; i++) {
0679:                            Instruction newtgt = replacedInsns
0680:                                    .get(switchinsn.jump_insts[i]);
0681:                            if (newtgt != null) {
0682:                                switchinsn.jump_insts[i] = newtgt;
0683:                                newtgt.labelled = true;
0684:                            }
0685:                        }
0686:                    }
0687:
0688:                    insn = insn.next;
0689:                }
0690:            }
0691:
0692:            private void adjustExceptionTable() {
0693:                Code_attribute codeAttribute = method.locate_code_attribute();
0694:
0695:                for (int i = 0; i < codeAttribute.exception_table_length; i++) {
0696:                    exception_table_entry entry = codeAttribute.exception_table[i];
0697:
0698:                    Instruction oldinsn = entry.start_inst;
0699:                    Instruction newinsn = replacedInsns.get(oldinsn);
0700:                    if (newinsn != null)
0701:                        entry.start_inst = newinsn;
0702:
0703:                    oldinsn = entry.end_inst;
0704:                    if (entry.end_inst != null) {
0705:                        newinsn = replacedInsns.get(oldinsn);
0706:                        if (newinsn != null)
0707:                            entry.end_inst = newinsn;
0708:                    }
0709:
0710:                    oldinsn = entry.handler_inst;
0711:                    newinsn = replacedInsns.get(oldinsn);
0712:                    if (newinsn != null)
0713:                        entry.handler_inst = newinsn;
0714:                }
0715:            }
0716:
0717:            private void adjustLineNumberTable() {
0718:                if (!Options.v().keep_line_number())
0719:                    return;
0720:                if (method.code_attr == null)
0721:                    return;
0722:
0723:                attribute_info[] attributes = method.code_attr.attributes;
0724:
0725:                for (attribute_info element : attributes) {
0726:                    if (element instanceof  LineNumberTable_attribute) {
0727:                        LineNumberTable_attribute lntattr = (LineNumberTable_attribute) element;
0728:                        for (line_number_table_entry element0 : lntattr.line_number_table) {
0729:                            Instruction oldinst = element0.start_inst;
0730:                            Instruction newinst = replacedInsns.get(oldinst);
0731:                            if (newinst != null)
0732:                                element0.start_inst = newinst;
0733:                        }
0734:                    }
0735:                }
0736:            }
0737:
0738:            /** Reconstructs the instruction stream by appending the Instruction
0739:             * lists associated with each basic block.
0740:             * <p>
0741:             * Note that this joins up the basic block Instruction lists, and so
0742:             * they will no longer end with <i>null</i> after this.
0743:             * @return the head of the list of instructions.
0744:             */
0745:            public Instruction reconstructInstructions() {
0746:                if (cfg != null)
0747:                    return cfg.head;
0748:                else
0749:                    return null;
0750:            }
0751:
0752:            /** Main.v() entry point for converting list of Instructions to Jimple statements;
0753:             * performs flow analysis, constructs Jimple statements, and fixes jumps.
0754:             * @param constant_pool constant pool of ClassFile.
0755:             * @param this_class constant pool index of the CONSTANT_Class_info object for
0756:             * this' class.
0757:             * @return <i>true</i> if all ok, <i>false</i> if there was an error.
0758:             * @see Stmt
0759:             */
0760:            public boolean jimplify(cp_info constant_pool[], int this _class,
0761:                    JimpleBody listBody) {
0762:                Util.v().setClassNameToAbbreviation(new HashMap());
0763:
0764:                Chain units = listBody.getUnits();
0765:
0766:                this .listBody = listBody;
0767:                this .units = units;
0768:                instructionToFirstStmt = new HashMap<Instruction, Stmt>();
0769:                instructionToLastStmt = new HashMap<Instruction, Stmt>();
0770:
0771:                jmethod = listBody.getMethod();
0772:                cm = Scene.v();
0773:
0774:                //TypeArray.setClassManager(cm);
0775:                //TypeStack.setClassManager(cm);
0776:
0777:                Set initialLocals = new ArraySet();
0778:
0779:                List parameterTypes = jmethod.getParameterTypes();
0780:
0781:                // Initialize nameToLocal which is an index*Type->Local map, which is used
0782:                // to determine local in bytecode references.
0783:                {
0784:                    Code_attribute ca = method.locate_code_attribute();
0785:                    LocalVariableTable_attribute la = ca
0786:                            .findLocalVariableTable();
0787:                    LocalVariableTypeTable_attribute lt = ca
0788:                            .findLocalVariableTypeTable();
0789:
0790:                    Util.v().activeVariableTable = la;
0791:                    Util.v().activeVariableTypeTable = lt;
0792:
0793:                    Util.v().activeConstantPool = constant_pool;
0794:
0795:                    Type this Type = RefType.v(jmethod.getDeclaringClass()
0796:                            .getName());
0797:                    boolean isStatic = Modifier
0798:                            .isStatic(jmethod.getModifiers());
0799:
0800:                    int currentLocalIndex = 0;
0801:
0802:                    // Initialize the 'this' variable
0803:                    {
0804:                        if (!isStatic) {
0805:                            String name;
0806:
0807:                            if (!Util.v().useFaithfulNaming || la == null)
0808:                                name = "l0";
0809:                            else {
0810:                                name = la.getLocalVariableName(constant_pool,
0811:                                        currentLocalIndex);
0812:                                if (!Util.v().isValidJimpleName(name))
0813:                                    name = "l0";
0814:                            }
0815:
0816:                            Local local = Jimple.v().newLocal(name,
0817:                                    UnknownType.v());
0818:
0819:                            listBody.getLocals().add(local);
0820:
0821:                            currentLocalIndex++;
0822:
0823:                            units.add(Jimple.v().newIdentityStmt(
0824:                                    local,
0825:                                    Jimple.v().newThisRef(
0826:                                            jmethod.getDeclaringClass()
0827:                                                    .getType())));
0828:                        }
0829:                    }
0830:
0831:                    // Initialize parameters
0832:                    {
0833:                        Iterator typeIt = parameterTypes.iterator();
0834:                        int argCount = 0;
0835:
0836:                        while (typeIt.hasNext()) {
0837:                            String name;
0838:                            Type type = (Type) typeIt.next();
0839:
0840:                            if (!Util.v().useFaithfulNaming || la == null)
0841:                                name = "l" + currentLocalIndex;
0842:                            else {
0843:                                name = la.getLocalVariableName(constant_pool,
0844:                                        currentLocalIndex);
0845:                                if (!Util.v().isValidJimpleName(name))
0846:                                    name = "l" + currentLocalIndex;
0847:                            }
0848:
0849:                            Local local = Jimple.v().newLocal(name,
0850:                                    UnknownType.v());
0851:                            initialLocals.add(local);
0852:                            listBody.getLocals().add(local);
0853:
0854:                            units
0855:                                    .add(Jimple.v().newIdentityStmt(
0856:                                            local,
0857:                                            Jimple.v().newParameterRef(type,
0858:                                                    argCount)));
0859:
0860:                            if (type.equals(DoubleType.v())
0861:                                    || type.equals(LongType.v())) {
0862:                                currentLocalIndex += 2;
0863:                            } else {
0864:                                currentLocalIndex += 1;
0865:                            }
0866:
0867:                            argCount++;
0868:                        }
0869:                    }
0870:
0871:                    Util.v().resetEasyNames();
0872:                }
0873:
0874:                jimplify(constant_pool, this _class);
0875:
0876:                return true;
0877:            }
0878:
0879:            private void buildInsnCFGfromBBCFG() {
0880:                BasicBlock block = cfg;
0881:
0882:                while (block != null) {
0883:                    Instruction insn = block.head;
0884:                    while (insn != block.tail) {
0885:                        Instruction[] succs = new Instruction[1];
0886:                        succs[0] = insn.next;
0887:                        insn.succs = succs;
0888:                        insn = insn.next;
0889:                    }
0890:
0891:                    {
0892:                        // The successors are the ones from the basic block.
0893:                        Vector<BasicBlock> bsucc = block.succ;
0894:                        int size = bsucc.size();
0895:                        Instruction[] succs = new Instruction[size];
0896:
0897:                        for (int i = 0; i < size; i++)
0898:                            succs[i] = bsucc.elementAt(i).head;
0899:                        insn.succs = succs;
0900:                    }
0901:
0902:                    block = block.next;
0903:                }
0904:            }
0905:
0906:            /** Main.v() entry point for converting list of Instructions to Jimple statements;
0907:             * performs flow analysis, constructs Jimple statements, and fixes jumps.
0908:             * @param constant_pool constant pool of ClassFile.
0909:             * @param this_class constant pool index of the CONSTANT_Class_info object for
0910:             * this' class.
0911:             * @param clearStacks if <i>true</i> semantic stacks will be deleted after
0912:             * the process is complete.
0913:             * @return <i>true</i> if all ok, <i>false</i> if there was an error.
0914:             * @see CFG#jimplify(cp_info[], int)
0915:             * @see Stmt
0916:             */
0917:            void jimplify(cp_info constant_pool[], int this _class) {
0918:                Code_attribute codeAttribute = method.locate_code_attribute();
0919:                Set<Instruction> handlerInstructions = new ArraySet();
0920:
0921:                Map<Instruction, SootClass> handlerInstructionToException = new HashMap<Instruction, SootClass>();
0922:                Map<Instruction, TypeStack> instructionToTypeStack;
0923:                Map<Instruction, TypeStack> instructionToPostTypeStack;
0924:
0925:                {
0926:                    // build graph in 
0927:                    buildInsnCFGfromBBCFG();
0928:
0929:                    // Put in successors due to exception handlers
0930:                    {
0931:                        for (int i = 0; i < codeAttribute.exception_table_length; i++) {
0932:                            Instruction startIns = codeAttribute.exception_table[i].start_inst;
0933:                            Instruction endIns = codeAttribute.exception_table[i].end_inst;
0934:                            Instruction handlerIns = codeAttribute.exception_table[i].handler_inst;
0935:
0936:                            handlerInstructions.add(handlerIns);
0937:
0938:                            // Determine exception to catch
0939:                            {
0940:                                int catchType = codeAttribute.exception_table[i].catch_type;
0941:
0942:                                SootClass exception;
0943:
0944:                                if (catchType != 0) {
0945:                                    CONSTANT_Class_info classinfo = (CONSTANT_Class_info) constant_pool[catchType];
0946:
0947:                                    String name = ((CONSTANT_Utf8_info) (constant_pool[classinfo.name_index]))
0948:                                            .convert();
0949:                                    name = name.replace('/', '.');
0950:
0951:                                    exception = cm.getSootClass(name);
0952:                                } else
0953:                                    exception = cm
0954:                                            .getSootClass("java.lang.Throwable");
0955:
0956:                                handlerInstructionToException.put(handlerIns,
0957:                                        exception);
0958:                            }
0959:
0960:                            if (startIns == endIns)
0961:                                throw new RuntimeException(
0962:                                        "Empty catch range for exception handler");
0963:
0964:                            Instruction ins = startIns;
0965:
0966:                            for (;;) {
0967:                                Instruction[] succs = ins.succs;
0968:                                Instruction[] newsuccs = new Instruction[succs.length + 1];
0969:
0970:                                System.arraycopy(succs, 0, newsuccs, 0,
0971:                                        succs.length);
0972:
0973:                                newsuccs[succs.length] = handlerIns;
0974:                                ins.succs = newsuccs;
0975:
0976:                                ins = ins.next;
0977:                                if (ins == endIns || ins == null)
0978:                                    break;
0979:                            }
0980:                        }
0981:                    }
0982:                }
0983:
0984:                Set<Instruction> reachableInstructions = new HashSet<Instruction>();
0985:
0986:                // Mark all the reachable instructions
0987:                {
0988:                    LinkedList<Instruction> instructionsToVisit = new LinkedList<Instruction>();
0989:
0990:                    reachableInstructions.add(firstInstruction);
0991:                    instructionsToVisit.addLast(firstInstruction);
0992:
0993:                    while (!instructionsToVisit.isEmpty()) {
0994:                        Instruction ins = instructionsToVisit.removeFirst();
0995:
0996:                        Instruction[] succs = ins.succs;
0997:
0998:                        for (Instruction succ : succs) {
0999:                            if (!reachableInstructions.contains(succ)) {
1000:                                reachableInstructions.add(succ);
1001:                                instructionsToVisit.addLast(succ);
1002:                            }
1003:                        }
1004:                    }
1005:                }
1006:
1007:                /*
1008:                // Check to see if any instruction is unmarked.
1009:                {
1010:                    BasicBlock b = cfg;
1011:
1012:                     while(b != null)
1013:                    {
1014:                        Instruction ins = b.head;
1015:
1016:                         while(ins != null)
1017:                        {
1018:                            if(!reachableInstructions.contains(ins))
1019:                                throw new RuntimeException("Method to jimplify contains unreachable code!  (not handled for now)");
1020:
1021:                             ins = ins.next;
1022:                        }
1023:
1024:                         b = b.next;
1025:                    }
1026:                }
1027:                 */
1028:
1029:                // Perform the flow analysis, and build up instructionToTypeStack and instructionToLocalArray
1030:                {
1031:                    instructionToTypeStack = new HashMap<Instruction, TypeStack>();
1032:                    instructionToPostTypeStack = new HashMap<Instruction, TypeStack>();
1033:
1034:                    Set<Instruction> visitedInstructions = new HashSet<Instruction>();
1035:                    List<Instruction> changedInstructions = new ArrayList<Instruction>();
1036:
1037:                    TypeStack initialTypeStack;
1038:
1039:                    // Build up initial type stack and initial local array (for the first instruction)
1040:                    {
1041:                        initialTypeStack = TypeStack.v();
1042:                        // the empty stack with nothing on it.
1043:                    }
1044:
1045:                    // Get the loop cranked up.
1046:                    {
1047:                        instructionToTypeStack.put(firstInstruction,
1048:                                initialTypeStack);
1049:
1050:                        visitedInstructions.add(firstInstruction);
1051:                        changedInstructions.add(firstInstruction);
1052:                    }
1053:
1054:                    {
1055:                        while (!changedInstructions.isEmpty()) {
1056:                            Instruction ins = changedInstructions.get(0);
1057:
1058:                            changedInstructions.remove(0);
1059:
1060:                            OutFlow ret = processFlow(ins,
1061:                                    instructionToTypeStack.get(ins),
1062:                                    constant_pool);
1063:
1064:                            instructionToPostTypeStack.put(ins, ret.typeStack);
1065:
1066:                            Instruction[] successors = ins.succs;
1067:
1068:                            for (Instruction s : successors) {
1069:                                if (!visitedInstructions.contains(s)) {
1070:                                    // Special case for the first time visiting.
1071:
1072:                                    if (handlerInstructions.contains(s)) {
1073:                                        TypeStack exceptionTypeStack = (TypeStack
1074:                                                .v())
1075:                                                .push(RefType
1076:                                                        .v(handlerInstructionToException
1077:                                                                .get(s)
1078:                                                                .getName()));
1079:
1080:                                        instructionToTypeStack.put(s,
1081:                                                exceptionTypeStack);
1082:                                    } else {
1083:                                        instructionToTypeStack.put(s,
1084:                                                ret.typeStack);
1085:                                    }
1086:
1087:                                    visitedInstructions.add(s);
1088:                                    changedInstructions.add(s);
1089:
1090:                                    // G.v().out.println("adding successor: " + s);
1091:                                } else {
1092:                                    // G.v().out.println("considering successor: " + s);
1093:
1094:                                    TypeStack newTypeStack, oldTypeStack = instructionToTypeStack
1095:                                            .get(s);
1096:
1097:                                    if (handlerInstructions.contains(s)) {
1098:                                        // The type stack for an instruction handler should always be that of
1099:                                        // single object on the stack.
1100:
1101:                                        TypeStack exceptionTypeStack = (TypeStack
1102:                                                .v())
1103:                                                .push(RefType
1104:                                                        .v(handlerInstructionToException
1105:                                                                .get(s)
1106:                                                                .getName()));
1107:
1108:                                        newTypeStack = exceptionTypeStack;
1109:                                    } else {
1110:                                        try {
1111:                                            newTypeStack = ret.typeStack
1112:                                                    .merge(oldTypeStack);
1113:                                        } catch (RuntimeException re) {
1114:                                            G.v().out.println("Considering "
1115:                                                    + s);
1116:                                            throw re;
1117:                                        }
1118:                                    }
1119:                                    if (!newTypeStack.equals(oldTypeStack)) {
1120:                                        changedInstructions.add(s);
1121:                                        // G.v().out.println("requires a revisit: " + s);
1122:                                    }
1123:
1124:                                    instructionToTypeStack.put(s, newTypeStack);
1125:                                }
1126:                            }
1127:                        }
1128:                    }
1129:                }
1130:
1131:                // Print out instructions + their localArray + typeStack
1132:                {
1133:                    Instruction ins = firstInstruction;
1134:
1135:                    //       G.v().out.println();
1136:
1137:                    while (ins != null) {
1138:                        TypeStack typeStack = instructionToTypeStack.get(ins);
1139:                        // TypeArray typeArray = (TypeArray) instructionToLocalArray.get(ins);
1140:                        /*
1141:                         G.v().out.println("[TypeArray]");
1142:                         typeArray.print(G.v().out);
1143:                         G.v().out.println();
1144:
1145:                         G.v().out.println("[TypeStack]");
1146:                         typeStack.print(G.v().out);
1147:                         G.v().out.println();
1148:
1149:                         G.v().out.println(ins.toString());
1150:                         */
1151:
1152:                        ins = ins.next;
1153:                        /*
1154:
1155:                         G.v().out.println();
1156:                         G.v().out.println();
1157:                         */
1158:
1159:                    }
1160:                }
1161:
1162:                // G.v().out.println("Producing Jimple code...");
1163:
1164:                // Jimplify each statement
1165:                {
1166:                    BasicBlock b = cfg;
1167:
1168:                    while (b != null) {
1169:                        Instruction ins = b.head;
1170:                        b.statements = new ArrayList<Stmt>();
1171:
1172:                        List<Stmt> blockStatements = b.statements;
1173:
1174:                        for (;;) {
1175:                            List<Stmt> statementsForIns = new ArrayList<Stmt>();
1176:
1177:                            if (reachableInstructions.contains(ins))
1178:                                generateJimple(ins, instructionToTypeStack
1179:                                        .get(ins), instructionToPostTypeStack
1180:                                        .get(ins), constant_pool,
1181:                                        statementsForIns, b);
1182:                            else
1183:                                statementsForIns.add(Jimple.v().newNopStmt());
1184:
1185:                            if (!statementsForIns.isEmpty()) {
1186:                                for (int i = 0; i < statementsForIns.size(); i++) {
1187:                                    units.add(statementsForIns.get(i));
1188:                                    blockStatements
1189:                                            .add(statementsForIns.get(i));
1190:                                }
1191:
1192:                                instructionToFirstStmt.put(ins,
1193:                                        statementsForIns.get(0));
1194:                                instructionToLastStmt.put(ins, statementsForIns
1195:                                        .get(statementsForIns.size() - 1));
1196:                            }
1197:
1198:                            if (ins == b.tail)
1199:                                break;
1200:
1201:                            ins = ins.next;
1202:                        }
1203:
1204:                        b = b.next;
1205:                    }
1206:                }
1207:
1208:                jimpleTargetFixup(); // fix up jump targets
1209:
1210:                /*
1211:                // Print out basic blocks
1212:                {
1213:                    BasicBlock b = cfg;
1214:
1215:                    G.v().out.println("Basic blocks for: " + jmethod.getName());
1216:
1217:                    while(b != null)
1218:                    {
1219:                        Instruction ins = b.head;
1220:
1221:                        G.v().out.println();
1222:
1223:                        while(ins != null)
1224:                        {
1225:                            G.v().out.println(ins.toString());
1226:                            ins = ins.next;
1227:                        }
1228:
1229:                        b = b.next;
1230:                    }
1231:                }
1232:                 */
1233:
1234:                // Insert beginCatch/endCatch statements for exception handling
1235:                {
1236:                    Map<Stmt, Stmt> targetToHandler = new HashMap<Stmt, Stmt>();
1237:
1238:                    for (int i = 0; i < codeAttribute.exception_table_length; i++) {
1239:                        Instruction startIns = codeAttribute.exception_table[i].start_inst;
1240:                        Instruction endIns = codeAttribute.exception_table[i].end_inst;
1241:                        Instruction targetIns = codeAttribute.exception_table[i].handler_inst;
1242:
1243:                        if (!instructionToFirstStmt.containsKey(startIns)
1244:                                || (endIns != null && (!instructionToLastStmt
1245:                                        .containsKey(endIns)))) {
1246:                            throw new RuntimeException(
1247:                                    "Exception range does not coincide with jimple instructions");
1248:                        }
1249:
1250:                        if (!instructionToFirstStmt.containsKey(targetIns)) {
1251:                            throw new RuntimeException(
1252:                                    "Exception handler does not coincide with jimple instruction");
1253:                        }
1254:
1255:                        SootClass exception;
1256:
1257:                        // Determine exception to catch
1258:                        {
1259:                            int catchType = codeAttribute.exception_table[i].catch_type;
1260:                            if (catchType != 0) {
1261:                                CONSTANT_Class_info classinfo = (CONSTANT_Class_info) constant_pool[catchType];
1262:
1263:                                String name = ((CONSTANT_Utf8_info) (constant_pool[classinfo.name_index]))
1264:                                        .convert();
1265:                                name = name.replace('/', '.');
1266:                                exception = cm.getSootClass(name);
1267:                            } else
1268:                                exception = cm
1269:                                        .getSootClass("java.lang.Throwable");
1270:                        }
1271:
1272:                        Stmt newTarget;
1273:
1274:                        // Insert assignment of exception
1275:                        {
1276:                            Stmt firstTargetStmt = instructionToFirstStmt
1277:                                    .get(targetIns);
1278:
1279:                            if (targetToHandler.containsKey(firstTargetStmt))
1280:                                newTarget = targetToHandler
1281:                                        .get(firstTargetStmt);
1282:                            else {
1283:                                Local local = Util.v()
1284:                                        .getLocalCreatingIfNecessary(listBody,
1285:                                                "$stack0", UnknownType.v());
1286:
1287:                                newTarget = Jimple.v().newIdentityStmt(local,
1288:                                        Jimple.v().newCaughtExceptionRef());
1289:
1290:                                // changed to account for catch blocks which are also part of normal control flow
1291:                                //units.insertBefore(newTarget, firstTargetStmt);			
1292:                                ((PatchingChain) units).insertBeforeNoRedirect(
1293:                                        newTarget, firstTargetStmt);
1294:
1295:                                targetToHandler.put(firstTargetStmt, newTarget);
1296:                                if (units.getFirst() != newTarget) {
1297:                                    Unit prev = (Unit) units
1298:                                            .getPredOf(newTarget);
1299:                                    if (prev != null && prev.fallsThrough())
1300:                                        units.insertAfter(Jimple.v()
1301:                                                .newGotoStmt(firstTargetStmt),
1302:                                                prev);
1303:                                }
1304:                            }
1305:                        }
1306:
1307:                        // Insert trap
1308:                        {
1309:                            Stmt firstStmt = instructionToFirstStmt
1310:                                    .get(startIns);
1311:                            Stmt afterEndStmt;
1312:                            if (endIns == null) {
1313:                                // A kludge which isn't really correct, but
1314:                                // gets us closer to correctness (until we
1315:                                // clean up the rest of Soot to properly
1316:                                // represent Traps which extend to the end 
1317:                                // of a method): if the protected code extends
1318:                                // to the end of the method, use the last Stmt
1319:                                // as the endUnit of the Trap, even though
1320:                                // that will leave the last unit outside
1321:                                // the protected area.
1322:                                afterEndStmt = (Stmt) units.getLast();
1323:                            } else {
1324:                                afterEndStmt = instructionToLastStmt
1325:                                        .get(endIns);
1326:                                IdentityStmt catchStart = (IdentityStmt) targetToHandler
1327:                                        .get(afterEndStmt);
1328:                                // (Cast to IdentityStmt as an assertion check.)
1329:                                if (catchStart != null) {
1330:                                    // The protected region extends to the beginning of an
1331:                                    // exception handler, so we need to reset afterEndStmt
1332:                                    // to the identity statement which we have inserted
1333:                                    // before the old afterEndStmt.
1334:                                    if (catchStart != units
1335:                                            .getPredOf(afterEndStmt)) {
1336:                                        throw new IllegalStateException(
1337:                                                "Assertion failure: catchStart != pred of afterEndStmt");
1338:                                    }
1339:                                    afterEndStmt = catchStart;
1340:                                }
1341:                            }
1342:
1343:                            Trap trap = Jimple.v().newTrap(exception,
1344:                                    firstStmt, afterEndStmt, newTarget);
1345:                            listBody.getTraps().add(trap);
1346:                        }
1347:                    }
1348:                }
1349:
1350:                /* convert line number table to tags attached to statements */
1351:                if (Options.v().keep_line_number()) {
1352:                    HashMap<Stmt, Tag> stmtstags = new HashMap<Stmt, Tag>();
1353:                    LinkedList<Stmt> startstmts = new LinkedList<Stmt>();
1354:
1355:                    attribute_info[] attrs = codeAttribute.attributes;
1356:                    for (attribute_info element : attrs) {
1357:                        if (element instanceof  LineNumberTable_attribute) {
1358:                            LineNumberTable_attribute lntattr = (LineNumberTable_attribute) element;
1359:                            for (line_number_table_entry element0 : lntattr.line_number_table) {
1360:                                Stmt start_stmt = instructionToFirstStmt
1361:                                        .get(element0.start_inst);
1362:
1363:                                if (start_stmt != null) {
1364:                                    LineNumberTag lntag = new LineNumberTag(
1365:                                            element0.line_number);
1366:                                    stmtstags.put(start_stmt, lntag);
1367:                                    startstmts.add(start_stmt);
1368:                                }
1369:                            }
1370:                        }
1371:                    }
1372:
1373:                    /* if the predecessor of a statement is a caughtexcetionref,
1374:                     * give it the tag of its successor */
1375:                    for (Iterator<Stmt> stmtIt = new ArrayList<Stmt>(stmtstags
1376:                            .keySet()).iterator(); stmtIt.hasNext();) {
1377:                        final Stmt stmt = stmtIt.next();
1378:                        Stmt pred = stmt;
1379:                        Tag tag = stmtstags.get(stmt);
1380:                        while (true) {
1381:                            pred = (Stmt) units.getPredOf(pred);
1382:                            if (pred == null)
1383:                                break;
1384:                            if (!(pred instanceof  IdentityStmt))
1385:                                break;
1386:                            stmtstags.put(pred, tag);
1387:                            pred.addTag(tag);
1388:                        }
1389:                    }
1390:
1391:                    /* attach line number tag to each statement. */
1392:                    for (int i = 0; i < startstmts.size(); i++) {
1393:                        Stmt stmt = startstmts.get(i);
1394:                        Tag tag = stmtstags.get(stmt);
1395:
1396:                        stmt.addTag(tag);
1397:
1398:                        stmt = (Stmt) units.getSuccOf(stmt);
1399:                        while (stmt != null && !stmtstags.containsKey(stmt)) {
1400:                            stmt.addTag(tag);
1401:                            stmt = (Stmt) units.getSuccOf(stmt);
1402:                        }
1403:                    }
1404:                }
1405:            }
1406:
1407:            private Type byteCodeTypeOf(Type type) {
1408:                if (type.equals(ShortType.v()) || type.equals(CharType.v())
1409:                        || type.equals(ByteType.v())
1410:                        || type.equals(BooleanType.v())) {
1411:                    return IntType.v();
1412:                } else
1413:                    return type;
1414:            }
1415:
1416:            OutFlow processFlow(Instruction ins, TypeStack typeStack,
1417:                    cp_info[] constant_pool) {
1418:                int x;
1419:                x = ((ins.code)) & 0xff;
1420:
1421:                switch (x) {
1422:                case ByteCode.BIPUSH:
1423:                    typeStack = typeStack.push(IntType.v());
1424:                    break;
1425:
1426:                case ByteCode.SIPUSH:
1427:                    typeStack = typeStack.push(IntType.v());
1428:                    break;
1429:
1430:                case ByteCode.LDC1:
1431:                    return processCPEntry(constant_pool,
1432:                            ((Instruction_Ldc1) ins).arg_b, typeStack, jmethod);
1433:
1434:                case ByteCode.LDC2:
1435:                case ByteCode.LDC2W:
1436:                    return processCPEntry(constant_pool,
1437:                            ((Instruction_intindex) ins).arg_i, typeStack,
1438:                            jmethod);
1439:
1440:                case ByteCode.ACONST_NULL:
1441:                    typeStack = typeStack.push(RefType.v("java.lang.Object"));
1442:                    break;
1443:
1444:                case ByteCode.ICONST_M1:
1445:                case ByteCode.ICONST_0:
1446:                case ByteCode.ICONST_1:
1447:                case ByteCode.ICONST_2:
1448:                case ByteCode.ICONST_3:
1449:                case ByteCode.ICONST_4:
1450:                case ByteCode.ICONST_5:
1451:                    typeStack = typeStack.push(IntType.v());
1452:                    break;
1453:                case ByteCode.LCONST_0:
1454:                case ByteCode.LCONST_1:
1455:                    typeStack = typeStack.push(LongType.v());
1456:                    typeStack = typeStack.push(Long2ndHalfType.v());
1457:                    break;
1458:                case ByteCode.FCONST_0:
1459:                case ByteCode.FCONST_1:
1460:                case ByteCode.FCONST_2:
1461:                    typeStack = typeStack.push(FloatType.v());
1462:                    break;
1463:                case ByteCode.DCONST_0:
1464:                case ByteCode.DCONST_1:
1465:                    typeStack = typeStack.push(DoubleType.v());
1466:                    typeStack = typeStack.push(Double2ndHalfType.v());
1467:                    break;
1468:                case ByteCode.ILOAD:
1469:                    typeStack = typeStack.push(IntType.v());
1470:                    break;
1471:
1472:                case ByteCode.FLOAD:
1473:                    typeStack = typeStack.push(FloatType.v());
1474:                    break;
1475:
1476:                case ByteCode.ALOAD:
1477:                    typeStack = typeStack.push(RefType.v("java.lang.Object"));
1478:                    // this is highly imprecise
1479:                    break;
1480:
1481:                case ByteCode.DLOAD:
1482:                    typeStack = typeStack.push(DoubleType.v());
1483:                    typeStack = typeStack.push(Double2ndHalfType.v());
1484:                    break;
1485:
1486:                case ByteCode.LLOAD:
1487:                    typeStack = typeStack.push(LongType.v());
1488:                    typeStack = typeStack.push(Long2ndHalfType.v());
1489:                    break;
1490:
1491:                case ByteCode.ILOAD_0:
1492:                case ByteCode.ILOAD_1:
1493:                case ByteCode.ILOAD_2:
1494:                case ByteCode.ILOAD_3:
1495:                    typeStack = typeStack.push(IntType.v());
1496:                    break;
1497:
1498:                case ByteCode.FLOAD_0:
1499:                case ByteCode.FLOAD_1:
1500:                case ByteCode.FLOAD_2:
1501:                case ByteCode.FLOAD_3:
1502:                    typeStack = typeStack.push(FloatType.v());
1503:                    break;
1504:
1505:                case ByteCode.ALOAD_0:
1506:                case ByteCode.ALOAD_1:
1507:                case ByteCode.ALOAD_2:
1508:                case ByteCode.ALOAD_3:
1509:                    typeStack = typeStack.push(RefType.v("java.lang.Object"));
1510:                    // this is highly imprecise
1511:                    break;
1512:
1513:                case ByteCode.LLOAD_0:
1514:                case ByteCode.LLOAD_1:
1515:                case ByteCode.LLOAD_2:
1516:                case ByteCode.LLOAD_3:
1517:                    typeStack = typeStack.push(LongType.v());
1518:                    typeStack = typeStack.push(Long2ndHalfType.v());
1519:                    break;
1520:
1521:                case ByteCode.DLOAD_0:
1522:                case ByteCode.DLOAD_1:
1523:                case ByteCode.DLOAD_2:
1524:                case ByteCode.DLOAD_3:
1525:                    typeStack = typeStack.push(DoubleType.v());
1526:                    typeStack = typeStack.push(Double2ndHalfType.v());
1527:                    break;
1528:
1529:                case ByteCode.ISTORE:
1530:                    typeStack = popSafe(typeStack, IntType.v());
1531:                    break;
1532:
1533:                case ByteCode.FSTORE:
1534:                    typeStack = popSafe(typeStack, FloatType.v());
1535:                    break;
1536:
1537:                case ByteCode.ASTORE:
1538:                    typeStack = typeStack.pop();
1539:                    break;
1540:
1541:                case ByteCode.LSTORE:
1542:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
1543:                    typeStack = popSafe(typeStack, LongType.v());
1544:                    break;
1545:
1546:                case ByteCode.DSTORE:
1547:                    typeStack = popSafe(typeStack, Double2ndHalfType.v());
1548:                    typeStack = popSafe(typeStack, DoubleType.v());
1549:                    break;
1550:
1551:                case ByteCode.ISTORE_0:
1552:                case ByteCode.ISTORE_1:
1553:                case ByteCode.ISTORE_2:
1554:                case ByteCode.ISTORE_3:
1555:                    typeStack = popSafe(typeStack, IntType.v());
1556:                    break;
1557:
1558:                case ByteCode.FSTORE_0:
1559:                case ByteCode.FSTORE_1:
1560:                case ByteCode.FSTORE_2:
1561:                case ByteCode.FSTORE_3:
1562:                    typeStack = popSafe(typeStack, FloatType.v());
1563:                    break;
1564:
1565:                case ByteCode.ASTORE_0:
1566:                case ByteCode.ASTORE_1:
1567:                case ByteCode.ASTORE_2:
1568:                case ByteCode.ASTORE_3:
1569:                    if (!(typeStack.top() instanceof  StmtAddressType)
1570:                            && !(typeStack.top() instanceof  RefType)
1571:                            && !(typeStack.top() instanceof  ArrayType)) {
1572:                        throw new RuntimeException(
1573:                                "Astore failed, invalid stack type: "
1574:                                        + typeStack.top());
1575:                    }
1576:
1577:                    typeStack = typeStack.pop();
1578:                    break;
1579:
1580:                case ByteCode.LSTORE_0:
1581:                case ByteCode.LSTORE_1:
1582:                case ByteCode.LSTORE_2:
1583:                case ByteCode.LSTORE_3:
1584:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
1585:                    typeStack = popSafe(typeStack, LongType.v());
1586:                    break;
1587:
1588:                case ByteCode.DSTORE_0:
1589:                case ByteCode.DSTORE_1:
1590:                case ByteCode.DSTORE_2:
1591:                case ByteCode.DSTORE_3:
1592:                    typeStack = popSafe(typeStack, Double2ndHalfType.v());
1593:                    typeStack = popSafe(typeStack, DoubleType.v());
1594:                    break;
1595:
1596:                case ByteCode.IINC:
1597:                    break;
1598:
1599:                case ByteCode.WIDE:
1600:                    throw new RuntimeException(
1601:                            "Wide instruction should not be encountered");
1602:                    // break;
1603:
1604:                case ByteCode.NEWARRAY: {
1605:                    typeStack = popSafe(typeStack, IntType.v());
1606:                    Type baseType = jimpleTypeOfAtype(((Instruction_Newarray) ins).atype);
1607:
1608:                    typeStack = typeStack.push(ArrayType.v(baseType, 1));
1609:                    break;
1610:                }
1611:
1612:                case ByteCode.ANEWARRAY: {
1613:                    CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[((Instruction_Anewarray) ins).arg_i];
1614:
1615:                    String name = ((CONSTANT_Utf8_info) (constant_pool[c.name_index]))
1616:                            .convert();
1617:                    name = name.replace('/', '.');
1618:
1619:                    Type baseType;
1620:
1621:                    if (name.startsWith("[")) {
1622:                        String baseName = getClassName(constant_pool,
1623:                                ((Instruction_Anewarray) ins).arg_i);
1624:                        baseType = Util.v().jimpleTypeOfFieldDescriptor(
1625:                                baseName);
1626:                    } else {
1627:                        baseType = RefType.v(name);
1628:                    }
1629:
1630:                    typeStack = popSafe(typeStack, IntType.v());
1631:                    typeStack = typeStack.push(baseType.makeArrayType());
1632:                    break;
1633:                }
1634:
1635:                case ByteCode.MULTIANEWARRAY: {
1636:                    int bdims = (((Instruction_Multianewarray) ins).dims);
1637:
1638:                    CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[((Instruction_Multianewarray) ins).arg_i];
1639:
1640:                    String arrayDescriptor = ((CONSTANT_Utf8_info) (constant_pool[c.name_index]))
1641:                            .convert();
1642:
1643:                    ArrayType arrayType = (ArrayType) Util.v()
1644:                            .jimpleTypeOfFieldDescriptor(arrayDescriptor);
1645:
1646:                    for (int j = 0; j < bdims; j++)
1647:                        typeStack = popSafe(typeStack, IntType.v());
1648:
1649:                    typeStack = typeStack.push(arrayType);
1650:                    break;
1651:                }
1652:
1653:                case ByteCode.ARRAYLENGTH:
1654:                    typeStack = popSafeRefType(typeStack);
1655:                    typeStack = typeStack.push(IntType.v());
1656:                    break;
1657:
1658:                case ByteCode.IALOAD:
1659:                case ByteCode.BALOAD:
1660:                case ByteCode.CALOAD:
1661:                case ByteCode.SALOAD:
1662:                    typeStack = popSafe(typeStack, IntType.v());
1663:                    typeStack = popSafeRefType(typeStack);
1664:                    typeStack = typeStack.push(IntType.v());
1665:                    break;
1666:                case ByteCode.FALOAD:
1667:                    typeStack = popSafe(typeStack, FloatType.v());
1668:                    typeStack = popSafeRefType(typeStack);
1669:                    typeStack = typeStack.push(FloatType.v());
1670:                    break;
1671:
1672:                case ByteCode.AALOAD: {
1673:
1674:                    typeStack = popSafe(typeStack, IntType.v());
1675:
1676:                    if (typeStack.top() instanceof  ArrayType) {
1677:                        ArrayType arrayType = (ArrayType) typeStack.top();
1678:                        typeStack = popSafeRefType(typeStack);
1679:
1680:                        if (arrayType.numDimensions == 1)
1681:                            typeStack = typeStack.push(arrayType.baseType);
1682:                        else
1683:                            typeStack = typeStack.push(ArrayType.v(
1684:                                    arrayType.baseType,
1685:                                    arrayType.numDimensions - 1));
1686:                    } else {
1687:                        // it's a null object
1688:
1689:                        typeStack = popSafeRefType(typeStack);
1690:
1691:                        typeStack = typeStack.push(RefType
1692:                                .v("java.lang.Object"));
1693:                    }
1694:
1695:                    break;
1696:                }
1697:                case ByteCode.LALOAD:
1698:                    typeStack = popSafe(typeStack, IntType.v());
1699:                    typeStack = popSafeRefType(typeStack);
1700:                    typeStack = typeStack.push(LongType.v());
1701:                    typeStack = typeStack.push(Long2ndHalfType.v());
1702:                    break;
1703:
1704:                case ByteCode.DALOAD:
1705:                    typeStack = popSafe(typeStack, IntType.v());
1706:                    typeStack = popSafeRefType(typeStack);
1707:                    typeStack = typeStack.push(DoubleType.v());
1708:                    typeStack = typeStack.push(Double2ndHalfType.v());
1709:                    break;
1710:
1711:                case ByteCode.IASTORE:
1712:                case ByteCode.BASTORE:
1713:                case ByteCode.CASTORE:
1714:                case ByteCode.SASTORE:
1715:                    typeStack = popSafe(typeStack, IntType.v());
1716:                    typeStack = popSafe(typeStack, IntType.v());
1717:                    typeStack = popSafeRefType(typeStack);
1718:                    break;
1719:
1720:                case ByteCode.AASTORE:
1721:                    typeStack = popSafeRefType(typeStack);
1722:                    typeStack = popSafe(typeStack, IntType.v());
1723:                    typeStack = popSafeRefType(typeStack);
1724:                    break;
1725:
1726:                case ByteCode.FASTORE:
1727:                    typeStack = popSafe(typeStack, FloatType.v());
1728:                    typeStack = popSafe(typeStack, IntType.v());
1729:                    typeStack = popSafeRefType(typeStack);
1730:                    break;
1731:
1732:                case ByteCode.LASTORE:
1733:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
1734:                    typeStack = popSafe(typeStack, LongType.v());
1735:                    typeStack = popSafe(typeStack, IntType.v());
1736:                    typeStack = popSafeRefType(typeStack);
1737:                    break;
1738:
1739:                case ByteCode.DASTORE:
1740:                    typeStack = popSafe(typeStack, Double2ndHalfType.v());
1741:                    typeStack = popSafe(typeStack, DoubleType.v());
1742:                    typeStack = popSafe(typeStack, IntType.v());
1743:                    typeStack = popSafeRefType(typeStack);
1744:                    break;
1745:
1746:                case ByteCode.NOP:
1747:                    break;
1748:
1749:                case ByteCode.POP:
1750:                    typeStack = typeStack.pop();
1751:                    break;
1752:
1753:                case ByteCode.POP2:
1754:                    typeStack = typeStack.pop();
1755:                    typeStack = typeStack.pop();
1756:                    break;
1757:
1758:                case ByteCode.DUP:
1759:                    typeStack = typeStack.push(typeStack.top());
1760:                    break;
1761:
1762:                case ByteCode.DUP2: {
1763:                    Type topType = typeStack.get(typeStack.topIndex()), secondType = typeStack
1764:                            .get(typeStack.topIndex() - 1);
1765:                    typeStack = (typeStack.push(secondType)).push(topType);
1766:                    break;
1767:                }
1768:
1769:                case ByteCode.DUP_X1: {
1770:                    Type topType = typeStack.get(typeStack.topIndex()), secondType = typeStack
1771:                            .get(typeStack.topIndex() - 1);
1772:
1773:                    typeStack = typeStack.pop().pop();
1774:
1775:                    typeStack = typeStack.push(topType).push(secondType).push(
1776:                            topType);
1777:                    break;
1778:                }
1779:
1780:                case ByteCode.DUP_X2: {
1781:                    Type topType = typeStack.get(typeStack.topIndex()), secondType = typeStack
1782:                            .get(typeStack.topIndex() - 1), thirdType = typeStack
1783:                            .get(typeStack.topIndex() - 2);
1784:
1785:                    typeStack = typeStack.pop().pop().pop();
1786:
1787:                    typeStack = typeStack.push(topType).push(thirdType).push(
1788:                            secondType).push(topType);
1789:                    break;
1790:                }
1791:
1792:                case ByteCode.DUP2_X1: {
1793:                    Type topType = typeStack.get(typeStack.topIndex()), secondType = typeStack
1794:                            .get(typeStack.topIndex() - 1), thirdType = typeStack
1795:                            .get(typeStack.topIndex() - 2);
1796:
1797:                    typeStack = typeStack.pop().pop().pop();
1798:
1799:                    typeStack = typeStack.push(secondType).push(topType).push(
1800:                            thirdType).push(secondType).push(topType);
1801:                    break;
1802:                }
1803:
1804:                case ByteCode.DUP2_X2: {
1805:                    Type topType = typeStack.get(typeStack.topIndex()), secondType = typeStack
1806:                            .get(typeStack.topIndex() - 1), thirdType = typeStack
1807:                            .get(typeStack.topIndex() - 2), fourthType = typeStack
1808:                            .get(typeStack.topIndex() - 3);
1809:
1810:                    typeStack = typeStack.pop().pop().pop().pop();
1811:
1812:                    typeStack = typeStack.push(secondType).push(topType).push(
1813:                            fourthType).push(thirdType).push(secondType).push(
1814:                            topType);
1815:                    break;
1816:                }
1817:
1818:                case ByteCode.SWAP: {
1819:                    Type topType = typeStack.top();
1820:
1821:                    typeStack = typeStack.pop();
1822:
1823:                    Type secondType = typeStack.top();
1824:
1825:                    typeStack = typeStack.pop();
1826:
1827:                    typeStack = typeStack.push(topType);
1828:                    typeStack = typeStack.push(secondType);
1829:                    break;
1830:                }
1831:
1832:                case ByteCode.IADD:
1833:                case ByteCode.ISUB:
1834:                case ByteCode.IMUL:
1835:                case ByteCode.IDIV:
1836:                case ByteCode.IREM:
1837:                case ByteCode.ISHL:
1838:                case ByteCode.ISHR:
1839:                case ByteCode.IUSHR:
1840:                case ByteCode.IAND:
1841:                case ByteCode.IOR:
1842:                case ByteCode.IXOR:
1843:                    typeStack = popSafe(typeStack, IntType.v());
1844:                    typeStack = popSafe(typeStack, IntType.v());
1845:                    typeStack = typeStack.push(IntType.v());
1846:                    break;
1847:
1848:                case ByteCode.LUSHR:
1849:                case ByteCode.LSHR:
1850:                case ByteCode.LSHL:
1851:                    typeStack = popSafe(typeStack, IntType.v());
1852:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
1853:                    typeStack = popSafe(typeStack, LongType.v());
1854:                    typeStack = typeStack.push(LongType.v());
1855:                    typeStack = typeStack.push(Long2ndHalfType.v());
1856:                    break;
1857:
1858:                case ByteCode.LREM:
1859:                case ByteCode.LDIV:
1860:                case ByteCode.LMUL:
1861:                case ByteCode.LSUB:
1862:                case ByteCode.LADD:
1863:                case ByteCode.LAND:
1864:                case ByteCode.LOR:
1865:                case ByteCode.LXOR:
1866:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
1867:                    typeStack = popSafe(typeStack, LongType.v());
1868:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
1869:                    typeStack = popSafe(typeStack, LongType.v());
1870:                    typeStack = typeStack.push(LongType.v());
1871:                    typeStack = typeStack.push(Long2ndHalfType.v());
1872:                    break;
1873:
1874:                case ByteCode.FREM:
1875:                case ByteCode.FDIV:
1876:                case ByteCode.FMUL:
1877:                case ByteCode.FSUB:
1878:                case ByteCode.FADD:
1879:                    typeStack = popSafe(typeStack, FloatType.v());
1880:                    typeStack = popSafe(typeStack, FloatType.v());
1881:                    typeStack = typeStack.push(FloatType.v());
1882:                    break;
1883:
1884:                case ByteCode.DREM:
1885:                case ByteCode.DDIV:
1886:                case ByteCode.DMUL:
1887:                case ByteCode.DSUB:
1888:                case ByteCode.DADD:
1889:                    typeStack = popSafe(typeStack, Double2ndHalfType.v());
1890:                    typeStack = popSafe(typeStack, DoubleType.v());
1891:                    typeStack = popSafe(typeStack, Double2ndHalfType.v());
1892:                    typeStack = popSafe(typeStack, DoubleType.v());
1893:                    typeStack = typeStack.push(DoubleType.v());
1894:                    typeStack = typeStack.push(Double2ndHalfType.v());
1895:                    break;
1896:
1897:                case ByteCode.INEG:
1898:                case ByteCode.LNEG:
1899:                case ByteCode.FNEG:
1900:                case ByteCode.DNEG:
1901:                    // Doesn't check to see if the required types are on the stack, but it should
1902:                    // if it wanted to be safe.
1903:                    break;
1904:
1905:                case ByteCode.I2L:
1906:                    typeStack = popSafe(typeStack, IntType.v());
1907:                    typeStack = typeStack.push(LongType.v());
1908:                    typeStack = typeStack.push(Long2ndHalfType.v());
1909:                    break;
1910:
1911:                case ByteCode.I2F:
1912:                    typeStack = popSafe(typeStack, IntType.v());
1913:                    typeStack = typeStack.push(FloatType.v());
1914:                    break;
1915:
1916:                case ByteCode.I2D:
1917:                    typeStack = popSafe(typeStack, IntType.v());
1918:                    typeStack = typeStack.push(DoubleType.v());
1919:                    typeStack = typeStack.push(Double2ndHalfType.v());
1920:                    break;
1921:
1922:                case ByteCode.L2I:
1923:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
1924:                    typeStack = popSafe(typeStack, LongType.v());
1925:                    typeStack = typeStack.push(IntType.v());
1926:                    break;
1927:
1928:                case ByteCode.L2F:
1929:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
1930:                    typeStack = popSafe(typeStack, LongType.v());
1931:                    typeStack = typeStack.push(FloatType.v());
1932:                    break;
1933:
1934:                case ByteCode.L2D:
1935:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
1936:                    typeStack = popSafe(typeStack, LongType.v());
1937:                    typeStack = typeStack.push(DoubleType.v());
1938:                    typeStack = typeStack.push(Double2ndHalfType.v());
1939:                    break;
1940:
1941:                case ByteCode.F2I:
1942:                    typeStack = popSafe(typeStack, FloatType.v());
1943:                    typeStack = typeStack.push(IntType.v());
1944:                    break;
1945:
1946:                case ByteCode.F2L:
1947:                    typeStack = popSafe(typeStack, FloatType.v());
1948:                    typeStack = typeStack.push(LongType.v());
1949:                    typeStack = typeStack.push(Long2ndHalfType.v());
1950:                    break;
1951:
1952:                case ByteCode.F2D:
1953:                    typeStack = popSafe(typeStack, FloatType.v());
1954:                    typeStack = typeStack.push(DoubleType.v());
1955:                    typeStack = typeStack.push(Double2ndHalfType.v());
1956:                    break;
1957:
1958:                case ByteCode.D2I:
1959:                    typeStack = popSafe(typeStack, Double2ndHalfType.v());
1960:                    typeStack = popSafe(typeStack, DoubleType.v());
1961:                    typeStack = typeStack.push(IntType.v());
1962:                    break;
1963:
1964:                case ByteCode.D2L:
1965:                    typeStack = popSafe(typeStack, Double2ndHalfType.v());
1966:                    typeStack = popSafe(typeStack, DoubleType.v());
1967:                    typeStack = typeStack.push(LongType.v());
1968:                    typeStack = typeStack.push(Long2ndHalfType.v());
1969:                    break;
1970:
1971:                case ByteCode.D2F:
1972:                    typeStack = popSafe(typeStack, Double2ndHalfType.v());
1973:                    typeStack = popSafe(typeStack, DoubleType.v());
1974:                    typeStack = typeStack.push(FloatType.v());
1975:                    break;
1976:
1977:                case ByteCode.INT2BYTE:
1978:                    break;
1979:                case ByteCode.INT2CHAR:
1980:                    break;
1981:                case ByteCode.INT2SHORT:
1982:                    break;
1983:
1984:                case ByteCode.IFEQ:
1985:                case ByteCode.IFGT:
1986:                case ByteCode.IFLT:
1987:                case ByteCode.IFLE:
1988:                case ByteCode.IFNE:
1989:                case ByteCode.IFGE:
1990:                    typeStack = popSafe(typeStack, IntType.v());
1991:                    break;
1992:
1993:                case ByteCode.IFNULL:
1994:                case ByteCode.IFNONNULL:
1995:                    typeStack = popSafeRefType(typeStack);
1996:                    break;
1997:
1998:                case ByteCode.IF_ICMPEQ:
1999:                case ByteCode.IF_ICMPLT:
2000:                case ByteCode.IF_ICMPLE:
2001:                case ByteCode.IF_ICMPNE:
2002:                case ByteCode.IF_ICMPGT:
2003:                case ByteCode.IF_ICMPGE:
2004:                    typeStack = popSafe(typeStack, IntType.v());
2005:                    typeStack = popSafe(typeStack, IntType.v());
2006:                    break;
2007:
2008:                case ByteCode.LCMP:
2009:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
2010:                    typeStack = popSafe(typeStack, LongType.v());
2011:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
2012:                    typeStack = popSafe(typeStack, LongType.v());
2013:                    typeStack = typeStack.push(IntType.v());
2014:                    break;
2015:
2016:                case ByteCode.FCMPL:
2017:                case ByteCode.FCMPG:
2018:                    typeStack = popSafe(typeStack, FloatType.v());
2019:                    typeStack = popSafe(typeStack, FloatType.v());
2020:                    typeStack = typeStack.push(IntType.v());
2021:                    break;
2022:
2023:                case ByteCode.DCMPL:
2024:                case ByteCode.DCMPG:
2025:                    typeStack = popSafe(typeStack, Double2ndHalfType.v());
2026:                    typeStack = popSafe(typeStack, DoubleType.v());
2027:                    typeStack = popSafe(typeStack, Double2ndHalfType.v());
2028:                    typeStack = popSafe(typeStack, DoubleType.v());
2029:                    typeStack = typeStack.push(IntType.v());
2030:                    break;
2031:
2032:                case ByteCode.IF_ACMPEQ:
2033:                case ByteCode.IF_ACMPNE:
2034:                    typeStack = popSafeRefType(typeStack);
2035:                    typeStack = popSafeRefType(typeStack);
2036:                    break;
2037:
2038:                case ByteCode.GOTO:
2039:                case ByteCode.GOTO_W:
2040:                    break;
2041:
2042:                case ByteCode.JSR:
2043:                case ByteCode.JSR_W:
2044:                    typeStack = typeStack.push(StmtAddressType.v());
2045:                    break;
2046:
2047:                case ByteCode.RET:
2048:                    break;
2049:
2050:                case ByteCode.RET_W:
2051:                    break;
2052:
2053:                case ByteCode.RETURN:
2054:                    break;
2055:
2056:                case ByteCode.IRETURN:
2057:                    typeStack = popSafe(typeStack, IntType.v());
2058:                    break;
2059:
2060:                case ByteCode.FRETURN:
2061:                    typeStack = popSafe(typeStack, FloatType.v());
2062:                    break;
2063:
2064:                case ByteCode.ARETURN:
2065:                    typeStack = popSafeRefType(typeStack);
2066:                    break;
2067:
2068:                case ByteCode.DRETURN:
2069:                    typeStack = popSafe(typeStack, Double2ndHalfType.v());
2070:                    typeStack = popSafe(typeStack, DoubleType.v());
2071:                    break;
2072:
2073:                case ByteCode.LRETURN:
2074:                    typeStack = popSafe(typeStack, Long2ndHalfType.v());
2075:                    typeStack = popSafe(typeStack, LongType.v());
2076:                    break;
2077:
2078:                case ByteCode.BREAKPOINT:
2079:                    break;
2080:
2081:                case ByteCode.TABLESWITCH:
2082:                    typeStack = popSafe(typeStack, IntType.v());
2083:                    break;
2084:
2085:                case ByteCode.LOOKUPSWITCH:
2086:                    typeStack = popSafe(typeStack, IntType.v());
2087:                    break;
2088:
2089:                case ByteCode.PUTFIELD: {
2090:                    Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm,
2091:                            constant_pool, ((Instruction_Putfield) ins).arg_i));
2092:
2093:                    if (type.equals(DoubleType.v())) {
2094:                        typeStack = popSafe(typeStack, Double2ndHalfType.v());
2095:                        typeStack = popSafe(typeStack, DoubleType.v());
2096:                    } else if (type.equals(LongType.v())) {
2097:                        typeStack = popSafe(typeStack, Long2ndHalfType.v());
2098:                        typeStack = popSafe(typeStack, LongType.v());
2099:                    } else if (type instanceof  RefType)
2100:                        typeStack = popSafeRefType(typeStack);
2101:                    else
2102:                        typeStack = popSafe(typeStack, type);
2103:
2104:                    typeStack = popSafeRefType(typeStack);
2105:                    break;
2106:                }
2107:
2108:                case ByteCode.GETFIELD: {
2109:                    Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm,
2110:                            constant_pool, ((Instruction_Getfield) ins).arg_i));
2111:
2112:                    typeStack = popSafeRefType(typeStack);
2113:
2114:                    if (type.equals(DoubleType.v())) {
2115:                        typeStack = typeStack.push(DoubleType.v());
2116:                        typeStack = typeStack.push(Double2ndHalfType.v());
2117:                    } else if (type.equals(LongType.v())) {
2118:                        typeStack = typeStack.push(LongType.v());
2119:                        typeStack = typeStack.push(Long2ndHalfType.v());
2120:                    } else
2121:                        typeStack = typeStack.push(type);
2122:                    break;
2123:                }
2124:
2125:                case ByteCode.PUTSTATIC: {
2126:                    Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm,
2127:                            constant_pool, ((Instruction_Putstatic) ins).arg_i));
2128:
2129:                    if (type.equals(DoubleType.v())) {
2130:                        typeStack = popSafe(typeStack, Double2ndHalfType.v());
2131:                        typeStack = popSafe(typeStack, DoubleType.v());
2132:                    } else if (type.equals(LongType.v())) {
2133:                        typeStack = popSafe(typeStack, Long2ndHalfType.v());
2134:                        typeStack = popSafe(typeStack, LongType.v());
2135:                    } else if (type instanceof  RefType)
2136:                        typeStack = popSafeRefType(typeStack);
2137:                    else
2138:                        typeStack = popSafe(typeStack, type);
2139:
2140:                    break;
2141:                }
2142:
2143:                case ByteCode.GETSTATIC: {
2144:                    Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm,
2145:                            constant_pool, ((Instruction_Getstatic) ins).arg_i));
2146:
2147:                    if (type.equals(DoubleType.v())) {
2148:                        typeStack = typeStack.push(DoubleType.v());
2149:                        typeStack = typeStack.push(Double2ndHalfType.v());
2150:                    } else if (type.equals(LongType.v())) {
2151:                        typeStack = typeStack.push(LongType.v());
2152:                        typeStack = typeStack.push(Long2ndHalfType.v());
2153:                    } else
2154:                        typeStack = typeStack.push(type);
2155:                    break;
2156:                }
2157:
2158:                case ByteCode.INVOKEVIRTUAL: {
2159:                    Instruction_Invokevirtual iv = (Instruction_Invokevirtual) ins;
2160:                    int args = cp_info.countParams(constant_pool, iv.arg_i);
2161:                    Type returnType = byteCodeTypeOf(jimpleReturnTypeOfMethodRef(
2162:                            cm, constant_pool, iv.arg_i));
2163:
2164:                    // pop off parameters.
2165:                    for (int j = args - 1; j >= 0; j--) {
2166:                        if (typeStack.top().equals(Long2ndHalfType.v())) {
2167:                            typeStack = popSafe(typeStack, Long2ndHalfType.v());
2168:                            typeStack = popSafe(typeStack, LongType.v());
2169:
2170:                        } else if (typeStack.top()
2171:                                .equals(Double2ndHalfType.v())) {
2172:                            typeStack = popSafe(typeStack, Double2ndHalfType
2173:                                    .v());
2174:                            typeStack = popSafe(typeStack, DoubleType.v());
2175:                        } else
2176:                            typeStack = popSafe(typeStack, typeStack.top());
2177:                    }
2178:
2179:                    typeStack = popSafeRefType(typeStack);
2180:
2181:                    if (!returnType.equals(VoidType.v()))
2182:                        typeStack = smartPush(typeStack, returnType);
2183:                    break;
2184:                }
2185:
2186:                case ByteCode.INVOKENONVIRTUAL: {
2187:                    Instruction_Invokenonvirtual iv = (Instruction_Invokenonvirtual) ins;
2188:                    int args = cp_info.countParams(constant_pool, iv.arg_i);
2189:                    Type returnType = byteCodeTypeOf(jimpleReturnTypeOfMethodRef(
2190:                            cm, constant_pool, iv.arg_i));
2191:
2192:                    // pop off parameters.
2193:                    for (int j = args - 1; j >= 0; j--) {
2194:                        if (typeStack.top().equals(Long2ndHalfType.v())) {
2195:                            typeStack = popSafe(typeStack, Long2ndHalfType.v());
2196:                            typeStack = popSafe(typeStack, LongType.v());
2197:
2198:                        } else if (typeStack.top()
2199:                                .equals(Double2ndHalfType.v())) {
2200:                            typeStack = popSafe(typeStack, Double2ndHalfType
2201:                                    .v());
2202:                            typeStack = popSafe(typeStack, DoubleType.v());
2203:                        } else
2204:                            typeStack = popSafe(typeStack, typeStack.top());
2205:                    }
2206:
2207:                    typeStack = popSafeRefType(typeStack);
2208:
2209:                    if (!returnType.equals(VoidType.v()))
2210:                        typeStack = smartPush(typeStack, returnType);
2211:                    break;
2212:                }
2213:
2214:                case ByteCode.INVOKESTATIC: {
2215:                    Instruction_Invokestatic iv = (Instruction_Invokestatic) ins;
2216:                    int args = cp_info.countParams(constant_pool, iv.arg_i);
2217:                    Type returnType = byteCodeTypeOf(jimpleReturnTypeOfMethodRef(
2218:                            cm, constant_pool, iv.arg_i));
2219:
2220:                    // pop off parameters.
2221:                    for (int j = args - 1; j >= 0; j--) {
2222:                        if (typeStack.top().equals(Long2ndHalfType.v())) {
2223:                            typeStack = popSafe(typeStack, Long2ndHalfType.v());
2224:                            typeStack = popSafe(typeStack, LongType.v());
2225:
2226:                        } else if (typeStack.top()
2227:                                .equals(Double2ndHalfType.v())) {
2228:                            typeStack = popSafe(typeStack, Double2ndHalfType
2229:                                    .v());
2230:                            typeStack = popSafe(typeStack, DoubleType.v());
2231:                        } else
2232:                            typeStack = popSafe(typeStack, typeStack.top());
2233:                    }
2234:
2235:                    if (!returnType.equals(VoidType.v()))
2236:                        typeStack = smartPush(typeStack, returnType);
2237:                    break;
2238:                }
2239:
2240:                case ByteCode.INVOKEINTERFACE: {
2241:                    Instruction_Invokeinterface iv = (Instruction_Invokeinterface) ins;
2242:                    int args = cp_info.countParams(constant_pool, iv.arg_i);
2243:                    Type returnType = byteCodeTypeOf(jimpleReturnTypeOfInterfaceMethodRef(
2244:                            cm, constant_pool, iv.arg_i));
2245:
2246:                    // pop off parameters.
2247:                    for (int j = args - 1; j >= 0; j--) {
2248:                        if (typeStack.top().equals(Long2ndHalfType.v())) {
2249:                            typeStack = popSafe(typeStack, Long2ndHalfType.v());
2250:                            typeStack = popSafe(typeStack, LongType.v());
2251:
2252:                        } else if (typeStack.top()
2253:                                .equals(Double2ndHalfType.v())) {
2254:                            typeStack = popSafe(typeStack, Double2ndHalfType
2255:                                    .v());
2256:                            typeStack = popSafe(typeStack, DoubleType.v());
2257:                        } else
2258:                            typeStack = popSafe(typeStack, typeStack.top());
2259:                    }
2260:
2261:                    typeStack = popSafeRefType(typeStack);
2262:
2263:                    if (!returnType.equals(VoidType.v()))
2264:                        typeStack = smartPush(typeStack, returnType);
2265:                    break;
2266:                }
2267:
2268:                case ByteCode.ATHROW:
2269:                    // technically athrow leaves the stack in an undefined
2270:                    // state.  In fact, the top value is the one we actually
2271:                    // throw, but it should stay on the stack since the exception
2272:                    // handler expects to start that way, at least in the real JVM.
2273:                    break;
2274:
2275:                case ByteCode.NEW: {
2276:                    Type type = RefType.v(getClassName(constant_pool,
2277:                            ((Instruction_New) ins).arg_i));
2278:
2279:                    typeStack = typeStack.push(type);
2280:                    break;
2281:                }
2282:
2283:                case ByteCode.CHECKCAST: {
2284:                    String className = getClassName(constant_pool,
2285:                            ((Instruction_Checkcast) ins).arg_i);
2286:
2287:                    Type castType;
2288:
2289:                    if (className.startsWith("["))
2290:                        castType = Util.v().jimpleTypeOfFieldDescriptor(
2291:                                getClassName(constant_pool,
2292:                                        ((Instruction_Checkcast) ins).arg_i));
2293:                    else
2294:                        castType = RefType.v(className);
2295:
2296:                    typeStack = popSafeRefType(typeStack);
2297:                    typeStack = typeStack.push(castType);
2298:                    break;
2299:                }
2300:
2301:                case ByteCode.INSTANCEOF: {
2302:                    typeStack = popSafeRefType(typeStack);
2303:                    typeStack = typeStack.push(IntType.v());
2304:                    break;
2305:                }
2306:
2307:                case ByteCode.MONITORENTER:
2308:                    typeStack = popSafeRefType(typeStack);
2309:                    break;
2310:                case ByteCode.MONITOREXIT:
2311:                    typeStack = popSafeRefType(typeStack);
2312:                    break;
2313:
2314:                default:
2315:                    throw new RuntimeException(
2316:                            "processFlow failed: Unknown bytecode instruction: "
2317:                                    + x);
2318:                }
2319:
2320:                return new OutFlow(typeStack);
2321:            }
2322:
2323:            private Type jimpleTypeOfFieldInFieldRef(Scene cm,
2324:                    cp_info[] constant_pool, int index) {
2325:                CONSTANT_Fieldref_info fr = (CONSTANT_Fieldref_info) (constant_pool[index]);
2326:
2327:                CONSTANT_NameAndType_info nat = (CONSTANT_NameAndType_info) (constant_pool[fr.name_and_type_index]);
2328:
2329:                String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[nat.descriptor_index]))
2330:                        .convert();
2331:
2332:                return Util.v().jimpleTypeOfFieldDescriptor(fieldDescriptor);
2333:            }
2334:
2335:            private Type jimpleReturnTypeOfMethodRef(Scene cm,
2336:                    cp_info[] constant_pool, int index) {
2337:                CONSTANT_Methodref_info mr = (CONSTANT_Methodref_info) (constant_pool[index]);
2338:
2339:                CONSTANT_NameAndType_info nat = (CONSTANT_NameAndType_info) (constant_pool[mr.name_and_type_index]);
2340:
2341:                String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[nat.descriptor_index]))
2342:                        .convert();
2343:
2344:                return Util.v().jimpleReturnTypeOfMethodDescriptor(
2345:                        methodDescriptor);
2346:            }
2347:
2348:            private Type jimpleReturnTypeOfInterfaceMethodRef(Scene cm,
2349:                    cp_info[] constant_pool, int index) {
2350:                CONSTANT_InterfaceMethodref_info mr = (CONSTANT_InterfaceMethodref_info) (constant_pool[index]);
2351:
2352:                CONSTANT_NameAndType_info nat = (CONSTANT_NameAndType_info) (constant_pool[mr.name_and_type_index]);
2353:
2354:                String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[nat.descriptor_index]))
2355:                        .convert();
2356:
2357:                return Util.v().jimpleReturnTypeOfMethodDescriptor(
2358:                        methodDescriptor);
2359:            }
2360:
2361:            private OutFlow processCPEntry(cp_info constant_pool[], int i,
2362:                    TypeStack typeStack, SootMethod jmethod) {
2363:                cp_info c = constant_pool[i];
2364:
2365:                if (c instanceof  CONSTANT_Integer_info)
2366:                    typeStack = typeStack.push(IntType.v());
2367:                else if (c instanceof  CONSTANT_Float_info)
2368:                    typeStack = typeStack.push(FloatType.v());
2369:                else if (c instanceof  CONSTANT_Long_info) {
2370:                    typeStack = typeStack.push(LongType.v());
2371:                    typeStack = typeStack.push(Long2ndHalfType.v());
2372:                } else if (c instanceof  CONSTANT_Double_info) {
2373:                    typeStack = typeStack.push(DoubleType.v());
2374:                    typeStack = typeStack.push(Double2ndHalfType.v());
2375:                } else if (c instanceof  CONSTANT_String_info)
2376:                    typeStack = typeStack.push(RefType.v("java.lang.String"));
2377:                else if (c instanceof  CONSTANT_Utf8_info)
2378:                    typeStack = typeStack.push(RefType.v("java.lang.String"));
2379:                else if (c instanceof  CONSTANT_Class_info) {
2380:                    CONSTANT_Class_info info = (CONSTANT_Class_info) c;
2381:                    String name = ((CONSTANT_Utf8_info) (constant_pool[info.name_index]))
2382:                            .convert();
2383:                    name = name.replace('/', '.');
2384:                    if (name.charAt(0) == '[') {
2385:                        int dim = 0;
2386:                        while (name.charAt(dim) == '[') {
2387:                            dim++;
2388:                        }
2389:                        // array type
2390:                        Type baseType = null;
2391:                        char typeIndicator = name.charAt(dim);
2392:                        switch (typeIndicator) {
2393:                        case 'I':
2394:                            baseType = IntType.v();
2395:                            break;
2396:                        case 'C':
2397:                            baseType = CharType.v();
2398:                            break;
2399:                        case 'F':
2400:                            baseType = FloatType.v();
2401:                            break;
2402:                        case 'D':
2403:                            baseType = DoubleType.v();
2404:                            break;
2405:                        case 'B':
2406:                            baseType = ByteType.v();
2407:                            break;
2408:                        case 'S':
2409:                            baseType = ShortType.v();
2410:                            break;
2411:                        case 'Z':
2412:                            baseType = BooleanType.v();
2413:                            break;
2414:                        case 'J':
2415:                            baseType = LongType.v();
2416:                            break;
2417:                        case 'L':
2418:                            baseType = RefType.v(name.substring(dim + 1, name
2419:                                    .length() - 1));
2420:                            break;
2421:                        default:
2422:                            throw new RuntimeException(
2423:                                    "Unknown Array Base Type in Class Constant");
2424:                        }
2425:                        typeStack = typeStack.push(ArrayType.v(baseType, dim));
2426:                    } else {
2427:                        typeStack = typeStack.push(RefType.v(name));
2428:                    }
2429:                } else
2430:                    throw new RuntimeException(
2431:                            "Attempting to push a non-constant cp entry"
2432:                                    + c.getClass());
2433:
2434:                return new OutFlow(typeStack);
2435:            }
2436:
2437:            TypeStack smartPush(TypeStack typeStack, Type type) {
2438:                if (type.equals(LongType.v())) {
2439:                    typeStack = typeStack.push(LongType.v());
2440:                    typeStack = typeStack.push(Long2ndHalfType.v());
2441:                } else if (type.equals(DoubleType.v())) {
2442:                    typeStack = typeStack.push(DoubleType.v());
2443:                    typeStack = typeStack.push(Double2ndHalfType.v());
2444:                } else
2445:                    typeStack = typeStack.push(type);
2446:
2447:                return typeStack;
2448:            }
2449:
2450:            TypeStack popSafeRefType(TypeStack typeStack) {
2451:                /*
2452:                if(!(typeStack.top() instanceof RefType) &&
2453:                    !(typeStack.top() instanceof ArrayType))
2454:                {
2455:                    throw new RuntimeException("popSafe failed; top: " + typeStack.top() +
2456:                            " required: RefType");
2457:                }
2458:                 */
2459:
2460:                return typeStack.pop();
2461:            }
2462:
2463:            TypeStack popSafeArrayType(TypeStack typeStack) {
2464:                /*
2465:                    if(!(typeStack.top() instanceof ArrayType) &&
2466:                        !(RefType.v("null").equals(typeStack.top())))
2467:                    {
2468:                        throw new RuntimeException("popSafe failed; top: " + typeStack.top() +
2469:                                " required: ArrayType");
2470:                    }
2471:                 */
2472:
2473:                return typeStack.pop();
2474:            }
2475:
2476:            TypeStack popSafe(TypeStack typeStack, Type requiredType) {
2477:                /*
2478:                    if(!typeStack.top().equals(requiredType))
2479:                        throw new RuntimeException("popSafe failed; top: " + typeStack.top() +
2480:                        " required: " + requiredType);
2481:                 */
2482:
2483:                return typeStack.pop();
2484:            }
2485:
2486:            void confirmType(Type actualType, Type requiredType) {
2487:                /*
2488:                    if(!actualType.equals(requiredType))
2489:                        throw new RuntimeException("confirmType failed; actualType: " + actualType +
2490:                            "  required: " + requiredType);*/
2491:            }
2492:
2493:            String getClassName(cp_info[] constant_pool, int index) {
2494:                CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[index];
2495:
2496:                String name = ((CONSTANT_Utf8_info) (constant_pool[c.name_index]))
2497:                        .convert();
2498:
2499:                return name.replace('/', '.');
2500:            }
2501:
2502:            void confirmRefType(Type actualType) {
2503:                /*
2504:                    if(!(actualType instanceof RefType) &&
2505:                        !(actualType instanceof ArrayType))
2506:                        throw new RuntimeException("confirmRefType failed; actualType: " + actualType);*/
2507:            }
2508:
2509:            /** Runs through the given bbq contents performing the target fix-up pass;
2510:             * Requires all reachable blocks to have their done flags set to true, and
2511:             * this resets them all back to false;
2512:             * @param bbq queue of BasicBlocks to process.
2513:             * @see jimpleTargetFixup
2514:             */
2515:            private void processTargetFixup(BBQ bbq) {
2516:                BasicBlock b, p;
2517:                Stmt s;
2518:                while (!bbq.isEmpty()) {
2519:                    try {
2520:                        b = bbq.pull();
2521:                    } catch (NoSuchElementException e) {
2522:                        break;
2523:                    }
2524:
2525:                    s = b.getTailJStmt();
2526:
2527:                    if (s instanceof  GotoStmt) {
2528:                        if (b.succ.size() == 1) {
2529:                            // Regular goto
2530:
2531:                            ((GotoStmt) s).setTarget(b.succ.firstElement()
2532:                                    .getHeadJStmt());
2533:                        } else {
2534:                            // Goto derived from a jsr bytecode		    
2535:                            /*
2536:                                    if((BasicBlock)(b.succ.firstElement())==b.next)
2537:                                        ((GotoStmt)s).setTarget(((BasicBlock) b.succ.elementAt(1)).getHeadJStmt());
2538:                                    else
2539:                                        ((GotoStmt)s).setTarget(((BasicBlock) b.succ.firstElement()).getHeadJStmt());	
2540:                             */
2541:                            G.v().out.println("Error :");
2542:                            for (int i = 0; i < b.statements.size(); i++)
2543:                                G.v().out.println(b.statements.get(i));
2544:
2545:                            throw new RuntimeException(b + " has "
2546:                                    + b.succ.size() + " successors.");
2547:                        }
2548:                    } else if (s instanceof  IfStmt) {
2549:                        if (b.succ.size() != 2)
2550:                            G.v().out
2551:                                    .println("How can an if not have 2 successors?");
2552:
2553:                        if ((b.succ.firstElement()) == b.next) {
2554:                            ((IfStmt) s).setTarget(b.succ.elementAt(1)
2555:                                    .getHeadJStmt());
2556:                        } else {
2557:                            ((IfStmt) s).setTarget(b.succ.firstElement()
2558:                                    .getHeadJStmt());
2559:                        }
2560:
2561:                    } else if (s instanceof  TableSwitchStmt) {
2562:                        int count = 0;
2563:                        TableSwitchStmt sts = (TableSwitchStmt) s;
2564:                        // Successors of the basic block ending with a switch statement
2565:                        // are listed in the successor vector in order, with the
2566:                        // default as the very first (0-th entry)
2567:
2568:                        for (BasicBlock basicBlock : b.succ) {
2569:                            p = (basicBlock);
2570:                            if (count == 0) {
2571:                                sts.setDefaultTarget(p.getHeadJStmt());
2572:                            } else {
2573:                                sts.setTarget(count - 1, p.getHeadJStmt());
2574:                            }
2575:                            count++;
2576:                        }
2577:                    } else if (s instanceof  LookupSwitchStmt) {
2578:                        int count = 0;
2579:                        LookupSwitchStmt sls = (LookupSwitchStmt) s;
2580:                        // Successors of the basic block ending with a switch statement
2581:                        // are listed in the successor vector in order, with the
2582:                        // default as the very first (0-th entry)
2583:
2584:                        for (BasicBlock basicBlock : b.succ) {
2585:                            p = (basicBlock);
2586:                            if (count == 0) {
2587:                                sls.setDefaultTarget(p.getHeadJStmt());
2588:                            } else {
2589:                                sls.setTarget(count - 1, p.getHeadJStmt());
2590:                            }
2591:                            count++;
2592:                        }
2593:                    }
2594:
2595:                    b.done = false;
2596:                    for (BasicBlock basicBlock : b.succ) {
2597:                        p = (basicBlock);
2598:                        if (p.done)
2599:                            bbq.push(p);
2600:                    }
2601:                }
2602:            }
2603:
2604:            /** After the initial jimple construction, a second pass is made to fix up
2605:             * missing Stmt targets for <tt>goto</tt>s, <tt>if</tt>'s etc.
2606:             * @param c code attribute of this method.
2607:             * @see CFG#jimplify
2608:             */
2609:            void jimpleTargetFixup() {
2610:                BasicBlock b;
2611:                BBQ bbq = new BBQ();
2612:
2613:                Code_attribute c = method.locate_code_attribute();
2614:                if (c == null)
2615:                    return;
2616:
2617:                // Reset all the dones to true
2618:                {
2619:                    BasicBlock bb = cfg;
2620:
2621:                    while (bb != null) {
2622:                        bb.done = true;
2623:                        bb = bb.next;
2624:                    }
2625:                }
2626:
2627:                // first process the main code
2628:                bbq.push(cfg);
2629:                processTargetFixup(bbq);
2630:
2631:                // then the exceptions
2632:                if (bbq.isEmpty()) {
2633:                    int i;
2634:                    for (i = 0; i < c.exception_table_length; i++) {
2635:                        b = c.exception_table[i].b;
2636:                        // if block hasn't yet been processed...
2637:                        if (b != null && b.done) {
2638:                            bbq.push(b);
2639:                            processTargetFixup(bbq);
2640:                            if (!bbq.isEmpty()) {
2641:                                G.v().out
2642:                                        .println("Error 2nd processing exception block.");
2643:                                break;
2644:                            }
2645:                        }
2646:                    }
2647:                }
2648:            }
2649:
2650:            private void generateJimpleForCPEntry(cp_info constant_pool[],
2651:                    int i, TypeStack typeStack, TypeStack postTypeStack,
2652:                    SootMethod jmethod, List<Stmt> statements) {
2653:                Stmt stmt;
2654:                Value rvalue;
2655:
2656:                cp_info c = constant_pool[i];
2657:
2658:                if (c instanceof  CONSTANT_Integer_info) {
2659:                    CONSTANT_Integer_info ci = (CONSTANT_Integer_info) c;
2660:
2661:                    rvalue = IntConstant.v((int) ci.bytes);
2662:                    stmt = Jimple.v().newAssignStmt(
2663:                            Util.v().getLocalForStackOp(listBody,
2664:                                    postTypeStack, postTypeStack.topIndex()),
2665:                            rvalue);
2666:                } else if (c instanceof  CONSTANT_Float_info) {
2667:                    CONSTANT_Float_info cf = (CONSTANT_Float_info) c;
2668:
2669:                    rvalue = FloatConstant.v(cf.convert());
2670:                    stmt = Jimple.v().newAssignStmt(
2671:                            Util.v().getLocalForStackOp(listBody,
2672:                                    postTypeStack, postTypeStack.topIndex()),
2673:                            rvalue);
2674:                } else if (c instanceof  CONSTANT_Long_info) {
2675:                    CONSTANT_Long_info cl = (CONSTANT_Long_info) c;
2676:
2677:                    rvalue = LongConstant.v(cl.convert());
2678:                    stmt = Jimple.v().newAssignStmt(
2679:                            Util.v().getLocalForStackOp(listBody,
2680:                                    postTypeStack, postTypeStack.topIndex()),
2681:                            rvalue);
2682:                } else if (c instanceof  CONSTANT_Double_info) {
2683:                    CONSTANT_Double_info cd = (CONSTANT_Double_info) c;
2684:
2685:                    rvalue = DoubleConstant.v(cd.convert());
2686:
2687:                    stmt = Jimple.v().newAssignStmt(
2688:                            Util.v().getLocalForStackOp(listBody,
2689:                                    postTypeStack, postTypeStack.topIndex()),
2690:                            rvalue);
2691:                } else if (c instanceof  CONSTANT_String_info) {
2692:                    CONSTANT_String_info cs = (CONSTANT_String_info) c;
2693:
2694:                    String constant = cs.toString(constant_pool);
2695:
2696:                    if (constant.startsWith("\"") && constant.endsWith("\""))
2697:                        constant = constant.substring(1, constant.length() - 1);
2698:
2699:                    rvalue = StringConstant.v(constant);
2700:                    stmt = Jimple.v().newAssignStmt(
2701:                            Util.v().getLocalForStackOp(listBody,
2702:                                    postTypeStack, postTypeStack.topIndex()),
2703:                            rvalue);
2704:                } else if (c instanceof  CONSTANT_Utf8_info) {
2705:                    CONSTANT_Utf8_info cu = (CONSTANT_Utf8_info) c;
2706:
2707:                    String constant = cu.convert();
2708:
2709:                    if (constant.startsWith("\"") && constant.endsWith("\""))
2710:                        constant = constant.substring(1, constant.length() - 1);
2711:
2712:                    rvalue = StringConstant.v(constant);
2713:                    stmt = Jimple.v().newAssignStmt(
2714:                            Util.v().getLocalForStackOp(listBody,
2715:                                    postTypeStack, postTypeStack.topIndex()),
2716:                            rvalue);
2717:                } else if (c instanceof  CONSTANT_Class_info) {
2718:
2719:                    String className = ((CONSTANT_Utf8_info) (constant_pool[((CONSTANT_Class_info) c).name_index]))
2720:                            .convert();
2721:
2722:                    rvalue = ClassConstant.v(className);
2723:                    stmt = Jimple.v().newAssignStmt(
2724:                            Util.v().getLocalForStackOp(listBody,
2725:                                    postTypeStack, postTypeStack.topIndex()),
2726:                            rvalue);
2727:                } else {
2728:                    throw new RuntimeException(
2729:                            "Attempting to push a non-constant cp entry" + c);
2730:                }
2731:
2732:                statements.add(stmt);
2733:            }
2734:
2735:            void generateJimple(Instruction ins, TypeStack typeStack,
2736:                    TypeStack postTypeStack, cp_info constant_pool[],
2737:                    List<Stmt> statements, BasicBlock basicBlock) {
2738:                Value[] params;
2739:                Local l1 = null, l2 = null, l3 = null, l4 = null;
2740:
2741:                Expr rhs = null;
2742:                ConditionExpr co = null;
2743:
2744:                ArrayRef a = null;
2745:                int args;
2746:                Value rvalue;
2747:
2748:                //      int localIndex;
2749:
2750:                Stmt stmt = null;
2751:
2752:                int x = ((ins.code)) & 0xff;
2753:
2754:                Util.v().activeOriginalIndex = ins.originalIndex;
2755:                Util.v().isLocalStore = false;
2756:                Util.v().isWideLocalStore = false;
2757:
2758:                switch (x) {
2759:                case ByteCode.BIPUSH:
2760:                    rvalue = IntConstant.v(((Instruction_Bipush) ins).arg_b);
2761:                    stmt = Jimple.v().newAssignStmt(
2762:                            Util.v().getLocalForStackOp(listBody,
2763:                                    postTypeStack, postTypeStack.topIndex()),
2764:                            rvalue);
2765:                    break;
2766:
2767:                case ByteCode.SIPUSH:
2768:                    rvalue = IntConstant.v(((Instruction_Sipush) ins).arg_i);
2769:                    stmt = Jimple.v().newAssignStmt(
2770:                            Util.v().getLocalForStackOp(listBody,
2771:                                    postTypeStack, postTypeStack.topIndex()),
2772:                            rvalue);
2773:                    break;
2774:
2775:                case ByteCode.LDC1:
2776:                    generateJimpleForCPEntry(constant_pool,
2777:                            ((Instruction_Ldc1) ins).arg_b, typeStack,
2778:                            postTypeStack, jmethod, statements);
2779:                    break;
2780:
2781:                case ByteCode.LDC2:
2782:                case ByteCode.LDC2W:
2783:                    generateJimpleForCPEntry(constant_pool,
2784:                            ((Instruction_intindex) ins).arg_i, typeStack,
2785:                            postTypeStack, jmethod, statements);
2786:                    break;
2787:
2788:                case ByteCode.ACONST_NULL:
2789:                    rvalue = NullConstant.v();
2790:                    stmt = Jimple.v().newAssignStmt(
2791:                            Util.v().getLocalForStackOp(listBody,
2792:                                    postTypeStack, postTypeStack.topIndex()),
2793:                            rvalue);
2794:                    break;
2795:
2796:                case ByteCode.ICONST_M1:
2797:                case ByteCode.ICONST_0:
2798:                case ByteCode.ICONST_1:
2799:                case ByteCode.ICONST_2:
2800:                case ByteCode.ICONST_3:
2801:                case ByteCode.ICONST_4:
2802:                case ByteCode.ICONST_5:
2803:                    rvalue = IntConstant.v(x - ByteCode.ICONST_0);
2804:                    stmt = Jimple.v().newAssignStmt(
2805:                            Util.v().getLocalForStackOp(listBody,
2806:                                    postTypeStack, postTypeStack.topIndex()),
2807:                            rvalue);
2808:                    break;
2809:
2810:                case ByteCode.LCONST_0:
2811:                case ByteCode.LCONST_1:
2812:                    rvalue = LongConstant.v(x - ByteCode.LCONST_0);
2813:                    stmt = Jimple.v().newAssignStmt(
2814:                            Util.v().getLocalForStackOp(listBody,
2815:                                    postTypeStack, postTypeStack.topIndex()),
2816:                            rvalue);
2817:                    break;
2818:
2819:                case ByteCode.FCONST_0:
2820:                case ByteCode.FCONST_1:
2821:                case ByteCode.FCONST_2:
2822:                    rvalue = FloatConstant.v((x - ByteCode.FCONST_0));
2823:                    stmt = Jimple.v().newAssignStmt(
2824:                            Util.v().getLocalForStackOp(listBody,
2825:                                    postTypeStack, postTypeStack.topIndex()),
2826:                            rvalue);
2827:                    break;
2828:
2829:                case ByteCode.DCONST_0:
2830:                case ByteCode.DCONST_1:
2831:                    rvalue = DoubleConstant.v((x - ByteCode.DCONST_0));
2832:                    stmt = Jimple.v().newAssignStmt(
2833:                            Util.v().getLocalForStackOp(listBody,
2834:                                    postTypeStack, postTypeStack.topIndex()),
2835:                            rvalue);
2836:                    break;
2837:
2838:                case ByteCode.ILOAD: {
2839:                    Local local = Util.v().getLocalForIndex(listBody,
2840:                            ((Instruction_bytevar) ins).arg_b);
2841:
2842:                    stmt = Jimple.v().newAssignStmt(
2843:                            Util.v().getLocalForStackOp(listBody,
2844:                                    postTypeStack, postTypeStack.topIndex()),
2845:                            local);
2846:                    break;
2847:                }
2848:
2849:                case ByteCode.FLOAD: {
2850:                    Local local = Util.v().getLocalForIndex(listBody,
2851:                            ((Instruction_bytevar) ins).arg_b);
2852:
2853:                    stmt = Jimple.v().newAssignStmt(
2854:                            Util.v().getLocalForStackOp(listBody,
2855:                                    postTypeStack, postTypeStack.topIndex()),
2856:                            local);
2857:                    break;
2858:                }
2859:
2860:                case ByteCode.ALOAD: {
2861:                    Local local = Util.v().getLocalForIndex(listBody,
2862:                            ((Instruction_bytevar) ins).arg_b);
2863:
2864:                    stmt = Jimple.v().newAssignStmt(
2865:                            Util.v().getLocalForStackOp(listBody,
2866:                                    postTypeStack, postTypeStack.topIndex()),
2867:                            local);
2868:                    break;
2869:                }
2870:
2871:                case ByteCode.DLOAD: {
2872:                    Local local = Util.v().getLocalForIndex(listBody,
2873:                            ((Instruction_bytevar) ins).arg_b);
2874:
2875:                    stmt = Jimple.v().newAssignStmt(
2876:                            Util.v().getLocalForStackOp(listBody,
2877:                                    postTypeStack, postTypeStack.topIndex()),
2878:                            local);
2879:                    break;
2880:                }
2881:
2882:                case ByteCode.LLOAD: {
2883:                    Local local = Util.v().getLocalForIndex(listBody,
2884:                            ((Instruction_bytevar) ins).arg_b);
2885:
2886:                    stmt = Jimple.v().newAssignStmt(
2887:                            Util.v().getLocalForStackOp(listBody,
2888:                                    postTypeStack, postTypeStack.topIndex()),
2889:                            local);
2890:                    break;
2891:                }
2892:
2893:                case ByteCode.ILOAD_0:
2894:                case ByteCode.ILOAD_1:
2895:                case ByteCode.ILOAD_2:
2896:                case ByteCode.ILOAD_3: {
2897:                    Local local = Util.v().getLocalForIndex(listBody,
2898:                            (x - ByteCode.ILOAD_0));
2899:
2900:                    stmt = Jimple.v().newAssignStmt(
2901:                            Util.v().getLocalForStackOp(listBody,
2902:                                    postTypeStack, postTypeStack.topIndex()),
2903:                            local);
2904:                    break;
2905:                }
2906:
2907:                case ByteCode.FLOAD_0:
2908:                case ByteCode.FLOAD_1:
2909:                case ByteCode.FLOAD_2:
2910:                case ByteCode.FLOAD_3: {
2911:                    Local local = Util.v().getLocalForIndex(listBody,
2912:                            (x - ByteCode.FLOAD_0));
2913:
2914:                    stmt = Jimple.v().newAssignStmt(
2915:                            Util.v().getLocalForStackOp(listBody,
2916:                                    postTypeStack, postTypeStack.topIndex()),
2917:                            local);
2918:                    break;
2919:                }
2920:
2921:                case ByteCode.ALOAD_0:
2922:                case ByteCode.ALOAD_1:
2923:                case ByteCode.ALOAD_2:
2924:                case ByteCode.ALOAD_3: {
2925:                    Local local = Util.v().getLocalForIndex(listBody,
2926:                            (x - ByteCode.ALOAD_0));
2927:
2928:                    stmt = Jimple.v().newAssignStmt(
2929:                            Util.v().getLocalForStackOp(listBody,
2930:                                    postTypeStack, postTypeStack.topIndex()),
2931:                            local);
2932:                    break;
2933:                }
2934:
2935:                case ByteCode.LLOAD_0:
2936:                case ByteCode.LLOAD_1:
2937:                case ByteCode.LLOAD_2:
2938:                case ByteCode.LLOAD_3: {
2939:                    Local local = Util.v().getLocalForIndex(listBody,
2940:                            (x - ByteCode.LLOAD_0));
2941:
2942:                    stmt = Jimple.v().newAssignStmt(
2943:                            Util.v().getLocalForStackOp(listBody,
2944:                                    postTypeStack, postTypeStack.topIndex()),
2945:                            local);
2946:                    break;
2947:                }
2948:
2949:                case ByteCode.DLOAD_0:
2950:                case ByteCode.DLOAD_1:
2951:                case ByteCode.DLOAD_2:
2952:                case ByteCode.DLOAD_3: {
2953:                    Local local = Util.v().getLocalForIndex(listBody,
2954:                            (x - ByteCode.DLOAD_0));
2955:
2956:                    stmt = Jimple.v().newAssignStmt(
2957:                            Util.v().getLocalForStackOp(listBody,
2958:                                    postTypeStack, postTypeStack.topIndex()),
2959:                            local);
2960:                    break;
2961:                }
2962:
2963:                case ByteCode.ISTORE: {
2964:                    Util.v().isLocalStore = true;
2965:                    Util.v().isWideLocalStore = true;
2966:
2967:                    Local local = Util.v().getLocalForIndex(listBody,
2968:                            ((Instruction_bytevar) ins).arg_b);
2969:
2970:                    stmt = Jimple.v().newAssignStmt(
2971:                            local,
2972:                            Util.v().getLocalForStackOp(listBody, typeStack,
2973:                                    typeStack.topIndex()));
2974:                    break;
2975:                }
2976:
2977:                case ByteCode.FSTORE: {
2978:                    Util.v().isLocalStore = true;
2979:                    Util.v().isWideLocalStore = true;
2980:
2981:                    Local local = Util.v().getLocalForIndex(listBody,
2982:                            ((Instruction_bytevar) ins).arg_b);
2983:
2984:                    stmt = Jimple.v().newAssignStmt(
2985:                            local,
2986:                            Util.v().getLocalForStackOp(listBody, typeStack,
2987:                                    typeStack.topIndex()));
2988:                    break;
2989:                }
2990:
2991:                case ByteCode.ASTORE: {
2992:                    Util.v().isLocalStore = true;
2993:                    Util.v().isWideLocalStore = true;
2994:
2995:                    Local local = Util.v().getLocalForIndex(listBody,
2996:                            ((Instruction_bytevar) ins).arg_b);
2997:
2998:                    stmt = Jimple.v().newAssignStmt(
2999:                            local,
3000:                            Util.v().getLocalForStackOp(listBody, typeStack,
3001:                                    typeStack.topIndex()));
3002:                    break;
3003:                }
3004:
3005:                case ByteCode.LSTORE: {
3006:                    Util.v().isLocalStore = true;
3007:                    Util.v().isWideLocalStore = true;
3008:
3009:                    Local local = Util.v().getLocalForIndex(listBody,
3010:                            ((Instruction_bytevar) ins).arg_b);
3011:
3012:                    stmt = Jimple.v().newAssignStmt(
3013:                            local,
3014:                            Util.v().getLocalForStackOp(listBody, typeStack,
3015:                                    typeStack.topIndex()));
3016:                    break;
3017:                }
3018:
3019:                case ByteCode.DSTORE: {
3020:                    Util.v().isLocalStore = true;
3021:                    Util.v().isWideLocalStore = true;
3022:
3023:                    Local local = Util.v().getLocalForIndex(listBody,
3024:                            ((Instruction_bytevar) ins).arg_b);
3025:
3026:                    stmt = Jimple.v().newAssignStmt(
3027:                            local,
3028:                            Util.v().getLocalForStackOp(listBody, typeStack,
3029:                                    typeStack.topIndex()));
3030:                    break;
3031:                }
3032:
3033:                case ByteCode.ISTORE_0:
3034:                case ByteCode.ISTORE_1:
3035:                case ByteCode.ISTORE_2:
3036:                case ByteCode.ISTORE_3: {
3037:                    Util.v().isLocalStore = true;
3038:                    Local local = Util.v().getLocalForIndex(listBody,
3039:                            (x - ByteCode.ISTORE_0));
3040:
3041:                    stmt = Jimple.v().newAssignStmt(
3042:                            local,
3043:                            Util.v().getLocalForStackOp(listBody, typeStack,
3044:                                    typeStack.topIndex()));
3045:                    break;
3046:                }
3047:
3048:                case ByteCode.FSTORE_0:
3049:                case ByteCode.FSTORE_1:
3050:                case ByteCode.FSTORE_2:
3051:                case ByteCode.FSTORE_3: {
3052:                    Util.v().isLocalStore = true;
3053:                    Local local = Util.v().getLocalForIndex(listBody,
3054:                            (x - ByteCode.FSTORE_0));
3055:
3056:                    stmt = Jimple.v().newAssignStmt(
3057:                            local,
3058:                            Util.v().getLocalForStackOp(listBody, typeStack,
3059:                                    typeStack.topIndex()));
3060:                    break;
3061:                }
3062:
3063:                case ByteCode.ASTORE_0:
3064:                case ByteCode.ASTORE_1:
3065:                case ByteCode.ASTORE_2:
3066:                case ByteCode.ASTORE_3: {
3067:                    Util.v().isLocalStore = true;
3068:                    Local local = Util.v().getLocalForIndex(listBody,
3069:                            (x - ByteCode.ASTORE_0));
3070:
3071:                    stmt = Jimple.v().newAssignStmt(
3072:                            local,
3073:                            Util.v().getLocalForStackOp(listBody, typeStack,
3074:                                    typeStack.topIndex()));
3075:                    break;
3076:                }
3077:
3078:                case ByteCode.LSTORE_0:
3079:                case ByteCode.LSTORE_1:
3080:                case ByteCode.LSTORE_2:
3081:                case ByteCode.LSTORE_3: {
3082:                    Util.v().isLocalStore = true;
3083:                    Local local = Util.v().getLocalForIndex(listBody,
3084:                            (x - ByteCode.LSTORE_0));
3085:
3086:                    stmt = Jimple.v().newAssignStmt(
3087:                            local,
3088:                            Util.v().getLocalForStackOp(listBody, typeStack,
3089:                                    typeStack.topIndex()));
3090:                    break;
3091:                }
3092:
3093:                case ByteCode.DSTORE_0:
3094:                case ByteCode.DSTORE_1:
3095:                case ByteCode.DSTORE_2:
3096:                case ByteCode.DSTORE_3: {
3097:                    Util.v().isLocalStore = true;
3098:                    Local local = Util.v().getLocalForIndex(listBody,
3099:                            (x - ByteCode.DSTORE_0));
3100:
3101:                    stmt = Jimple.v().newAssignStmt(
3102:                            local,
3103:                            Util.v().getLocalForStackOp(listBody, typeStack,
3104:                                    typeStack.topIndex()));
3105:                    break;
3106:                }
3107:
3108:                case ByteCode.IINC: {
3109:                    Local local = Util.v().getLocalForIndex(listBody,
3110:                            ((Instruction_Iinc) ins).arg_b);
3111:
3112:                    int amt = (((Instruction_Iinc) ins).arg_c);
3113:                    rhs = Jimple.v().newAddExpr(local, IntConstant.v(amt));
3114:                    stmt = Jimple.v().newAssignStmt(local, rhs);
3115:                    break;
3116:                }
3117:
3118:                case ByteCode.WIDE:
3119:                    throw new RuntimeException(
3120:                            "WIDE instruction should not be encountered anymore");
3121:                    // break;
3122:
3123:                case ByteCode.NEWARRAY: {
3124:                    Type baseType = jimpleTypeOfAtype(((Instruction_Newarray) ins).atype);
3125:
3126:                    rhs = Jimple.v().newNewArrayExpr(
3127:                            baseType,
3128:                            Util.v().getLocalForStackOp(listBody, typeStack,
3129:                                    typeStack.topIndex()));
3130:
3131:                    stmt = Jimple.v().newAssignStmt(
3132:                            Util.v().getLocalForStackOp(listBody,
3133:                                    postTypeStack, postTypeStack.topIndex()),
3134:                            rhs);
3135:
3136:                    break;
3137:                }
3138:
3139:                case ByteCode.ANEWARRAY: {
3140:                    String baseName = getClassName(constant_pool,
3141:                            ((Instruction_Anewarray) ins).arg_i);
3142:
3143:                    Type baseType;
3144:
3145:                    if (baseName.startsWith("["))
3146:                        baseType = Util.v().jimpleTypeOfFieldDescriptor(
3147:                                getClassName(constant_pool,
3148:                                        ((Instruction_Anewarray) ins).arg_i));
3149:                    else
3150:                        baseType = RefType.v(baseName);
3151:
3152:                    rhs = Jimple.v().newNewArrayExpr(
3153:                            baseType,
3154:                            Util.v().getLocalForStackOp(listBody, typeStack,
3155:                                    typeStack.topIndex()));
3156:
3157:                    stmt = Jimple.v().newAssignStmt(
3158:                            Util.v().getLocalForStackOp(listBody,
3159:                                    postTypeStack, postTypeStack.topIndex()),
3160:                            rhs);
3161:                    break;
3162:                }
3163:
3164:                case ByteCode.MULTIANEWARRAY: {
3165:                    int bdims = (((Instruction_Multianewarray) ins).dims);
3166:                    List dims = new ArrayList();
3167:
3168:                    for (int j = 0; j < bdims; j++)
3169:                        dims.add(Util.v()
3170:                                .getLocalForStackOp(listBody, typeStack,
3171:                                        typeStack.topIndex() - bdims + j + 1));
3172:
3173:                    String mstype = constant_pool[((Instruction_Multianewarray) ins).arg_i]
3174:                            .toString(constant_pool);
3175:
3176:                    ArrayType jimpleType = (ArrayType) Util.v()
3177:                            .jimpleTypeOfFieldDescriptor(mstype);
3178:
3179:                    rhs = Jimple.v().newNewMultiArrayExpr(jimpleType, dims);
3180:
3181:                    stmt = Jimple.v().newAssignStmt(
3182:                            Util.v().getLocalForStackOp(listBody,
3183:                                    postTypeStack, postTypeStack.topIndex()),
3184:                            rhs);
3185:                    break;
3186:                }
3187:
3188:                case ByteCode.ARRAYLENGTH:
3189:                    rhs = Jimple.v().newLengthExpr(
3190:                            Util.v().getLocalForStackOp(listBody, typeStack,
3191:                                    typeStack.topIndex()));
3192:
3193:                    stmt = Jimple.v().newAssignStmt(
3194:                            Util.v().getLocalForStackOp(listBody,
3195:                                    postTypeStack, postTypeStack.topIndex()),
3196:                            rhs);
3197:                    break;
3198:
3199:                case ByteCode.IALOAD:
3200:                case ByteCode.BALOAD:
3201:                case ByteCode.CALOAD:
3202:                case ByteCode.SALOAD:
3203:                case ByteCode.FALOAD:
3204:                case ByteCode.LALOAD:
3205:                case ByteCode.DALOAD:
3206:                case ByteCode.AALOAD:
3207:                    a = Jimple.v().newArrayRef(
3208:                            Util.v().getLocalForStackOp(listBody, typeStack,
3209:                                    typeStack.topIndex() - 1),
3210:                            Util.v().getLocalForStackOp(listBody, typeStack,
3211:                                    typeStack.topIndex()));
3212:
3213:                    stmt = Jimple.v()
3214:                            .newAssignStmt(
3215:                                    Util.v().getLocalForStackOp(listBody,
3216:                                            postTypeStack,
3217:                                            postTypeStack.topIndex()), a);
3218:
3219:                    break;
3220:
3221:                case ByteCode.IASTORE:
3222:                case ByteCode.FASTORE:
3223:                case ByteCode.AASTORE:
3224:                case ByteCode.BASTORE:
3225:                case ByteCode.CASTORE:
3226:                case ByteCode.SASTORE:
3227:                    a = Jimple.v().newArrayRef(
3228:                            Util.v().getLocalForStackOp(listBody, typeStack,
3229:                                    typeStack.topIndex() - 2),
3230:                            Util.v().getLocalForStackOp(listBody, typeStack,
3231:                                    typeStack.topIndex() - 1));
3232:
3233:                    stmt = Jimple.v().newAssignStmt(
3234:                            a,
3235:                            Util.v().getLocalForStackOp(listBody, typeStack,
3236:                                    typeStack.topIndex()));
3237:                    break;
3238:
3239:                case ByteCode.LASTORE:
3240:                case ByteCode.DASTORE:
3241:                    a = Jimple.v().newArrayRef(
3242:                            Util.v().getLocalForStackOp(listBody, typeStack,
3243:                                    typeStack.topIndex() - 3),
3244:                            Util.v().getLocalForStackOp(listBody, typeStack,
3245:                                    typeStack.topIndex() - 2));
3246:
3247:                    stmt = Jimple.v().newAssignStmt(
3248:                            a,
3249:                            Util.v().getLocalForStackOp(listBody, typeStack,
3250:                                    typeStack.topIndex()));
3251:                    break;
3252:
3253:                case ByteCode.NOP:
3254:                    stmt = Jimple.v().newNopStmt();
3255:                    break;
3256:
3257:                case ByteCode.POP:
3258:                case ByteCode.POP2:
3259:                    stmt = Jimple.v().newNopStmt();
3260:                    break;
3261:
3262:                case ByteCode.DUP:
3263:                    stmt = Jimple.v().newAssignStmt(
3264:                            Util.v().getLocalForStackOp(listBody,
3265:                                    postTypeStack, postTypeStack.topIndex()),
3266:                            Util.v().getLocalForStackOp(listBody, typeStack,
3267:                                    typeStack.topIndex()));
3268:                    break;
3269:
3270:                case ByteCode.DUP2:
3271:                    if (typeSize(typeStack.top()) == 2) {
3272:                        stmt = Jimple.v().newAssignStmt(
3273:                                Util.v().getLocalForStackOp(listBody,
3274:                                        postTypeStack,
3275:                                        postTypeStack.topIndex() - 1),
3276:                                Util.v().getLocalForStackOp(listBody,
3277:                                        typeStack, typeStack.topIndex() - 1));
3278:                    } else {
3279:                        stmt = Jimple.v().newAssignStmt(
3280:                                Util.v().getLocalForStackOp(listBody,
3281:                                        postTypeStack,
3282:                                        postTypeStack.topIndex() - 1),
3283:                                Util.v().getLocalForStackOp(listBody,
3284:                                        typeStack, typeStack.topIndex() - 1));
3285:
3286:                        statements.add(stmt);
3287:
3288:                        stmt = Jimple.v().newAssignStmt(
3289:                                Util.v()
3290:                                        .getLocalForStackOp(listBody,
3291:                                                postTypeStack,
3292:                                                postTypeStack.topIndex()),
3293:                                Util.v().getLocalForStackOp(listBody,
3294:                                        typeStack, typeStack.topIndex()));
3295:
3296:                        statements.add(stmt);
3297:
3298:                        stmt = null;
3299:                    }
3300:                    break;
3301:
3302:                case ByteCode.DUP_X1:
3303:                    l1 = Util.v().getLocalForStackOp(listBody, typeStack,
3304:                            typeStack.topIndex());
3305:                    l2 = Util.v().getLocalForStackOp(listBody, typeStack,
3306:                            typeStack.topIndex() - 1);
3307:
3308:                    stmt = Jimple.v().newAssignStmt(
3309:                            Util.v().getLocalForStackOp(listBody,
3310:                                    postTypeStack, postTypeStack.topIndex()),
3311:                            l1);
3312:
3313:                    statements.add(stmt);
3314:
3315:                    stmt = Jimple.v().newAssignStmt(
3316:                            Util.v()
3317:                                    .getLocalForStackOp(listBody,
3318:                                            postTypeStack,
3319:                                            postTypeStack.topIndex() - 1), l2);
3320:
3321:                    statements.add(stmt);
3322:
3323:                    stmt = Jimple.v().newAssignStmt(
3324:                            Util.v()
3325:                                    .getLocalForStackOp(listBody,
3326:                                            postTypeStack,
3327:                                            postTypeStack.topIndex() - 2),
3328:                            Util.v().getLocalForStackOp(listBody,
3329:                                    postTypeStack, postTypeStack.topIndex()));
3330:
3331:                    statements.add(stmt);
3332:
3333:                    stmt = null;
3334:                    break;
3335:
3336:                case ByteCode.DUP_X2:
3337:                    if (typeSize(typeStack.get(typeStack.topIndex() - 2)) == 2) {
3338:                        l3 = Util.v().getLocalForStackOp(listBody, typeStack,
3339:                                typeStack.topIndex() - 2);
3340:                        l1 = Util.v().getLocalForStackOp(listBody, typeStack,
3341:                                typeStack.topIndex());
3342:
3343:                        stmt = Jimple.v().newAssignStmt(
3344:                                Util.v().getLocalForStackOp(listBody,
3345:                                        postTypeStack,
3346:                                        postTypeStack.topIndex() - 2), l3);
3347:
3348:                        statements.add(stmt);
3349:
3350:                        stmt = Jimple.v().newAssignStmt(
3351:                                Util.v().getLocalForStackOp(listBody,
3352:                                        postTypeStack,
3353:                                        postTypeStack.topIndex() - 3), l1);
3354:
3355:                        statements.add(stmt);
3356:
3357:                        stmt = Jimple.v().newAssignStmt(
3358:                                Util.v()
3359:                                        .getLocalForStackOp(listBody,
3360:                                                postTypeStack,
3361:                                                postTypeStack.topIndex()), l1);
3362:
3363:                        statements.add(stmt);
3364:
3365:                        stmt = null;
3366:                    } else {
3367:                        l3 = Util.v().getLocalForStackOp(listBody, typeStack,
3368:                                typeStack.topIndex() - 2);
3369:                        l2 = Util.v().getLocalForStackOp(listBody, typeStack,
3370:                                typeStack.topIndex() - 1);
3371:                        l1 = Util.v().getLocalForStackOp(listBody, typeStack,
3372:                                typeStack.topIndex());
3373:
3374:                        stmt = Jimple.v().newAssignStmt(
3375:                                Util.v()
3376:                                        .getLocalForStackOp(listBody,
3377:                                                postTypeStack,
3378:                                                postTypeStack.topIndex()), l1);
3379:
3380:                        statements.add(stmt);
3381:
3382:                        stmt = Jimple.v().newAssignStmt(
3383:                                Util.v().getLocalForStackOp(listBody,
3384:                                        postTypeStack,
3385:                                        postTypeStack.topIndex() - 1), l2);
3386:
3387:                        statements.add(stmt);
3388:
3389:                        stmt = Jimple.v().newAssignStmt(
3390:                                Util.v().getLocalForStackOp(listBody,
3391:                                        postTypeStack,
3392:                                        postTypeStack.topIndex() - 2), l3);
3393:
3394:                        statements.add(stmt);
3395:
3396:                        stmt = Jimple.v().newAssignStmt(
3397:                                Util.v().getLocalForStackOp(listBody,
3398:                                        postTypeStack,
3399:                                        postTypeStack.topIndex() - 3),
3400:                                Util.v()
3401:                                        .getLocalForStackOp(listBody,
3402:                                                postTypeStack,
3403:                                                postTypeStack.topIndex()));
3404:
3405:                        statements.add(stmt);
3406:
3407:                        stmt = null;
3408:                    }
3409:                    break;
3410:
3411:                case ByteCode.DUP2_X1:
3412:                    if (typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2) {
3413:                        l2 = Util.v().getLocalForStackOp(listBody, typeStack,
3414:                                typeStack.topIndex() - 1);
3415:                        l3 = Util.v().getLocalForStackOp(listBody, typeStack,
3416:                                typeStack.topIndex() - 2);
3417:
3418:                        stmt = Jimple.v().newAssignStmt(
3419:                                Util.v().getLocalForStackOp(listBody,
3420:                                        postTypeStack,
3421:                                        postTypeStack.topIndex() - 1), l2);
3422:
3423:                        statements.add(stmt);
3424:
3425:                        stmt = Jimple.v().newAssignStmt(
3426:                                Util.v().getLocalForStackOp(listBody,
3427:                                        postTypeStack,
3428:                                        postTypeStack.topIndex() - 2), l3);
3429:
3430:                        statements.add(stmt);
3431:
3432:                        stmt = Jimple.v().newAssignStmt(
3433:                                Util.v().getLocalForStackOp(listBody,
3434:                                        postTypeStack,
3435:                                        postTypeStack.topIndex() - 4),
3436:                                Util.v().getLocalForStackOp(listBody,
3437:                                        postTypeStack,
3438:                                        postTypeStack.topIndex() - 1));
3439:
3440:                        statements.add(stmt);
3441:
3442:                        stmt = null;
3443:                    } else {
3444:                        l3 = Util.v().getLocalForStackOp(listBody, typeStack,
3445:                                typeStack.topIndex() - 2);
3446:                        l2 = Util.v().getLocalForStackOp(listBody, typeStack,
3447:                                typeStack.topIndex() - 1);
3448:                        l1 = Util.v().getLocalForStackOp(listBody, typeStack,
3449:                                typeStack.topIndex());
3450:
3451:                        stmt = Jimple.v().newAssignStmt(
3452:                                Util.v()
3453:                                        .getLocalForStackOp(listBody,
3454:                                                postTypeStack,
3455:                                                postTypeStack.topIndex()), l1);
3456:
3457:                        statements.add(stmt);
3458:
3459:                        stmt = Jimple.v().newAssignStmt(
3460:                                Util.v().getLocalForStackOp(listBody,
3461:                                        postTypeStack,
3462:                                        postTypeStack.topIndex() - 1), l2);
3463:
3464:                        statements.add(stmt);
3465:
3466:                        stmt = Jimple.v().newAssignStmt(
3467:                                Util.v().getLocalForStackOp(listBody,
3468:                                        postTypeStack,
3469:                                        postTypeStack.topIndex() - 2), l3);
3470:
3471:                        statements.add(stmt);
3472:
3473:                        stmt = Jimple.v().newAssignStmt(
3474:                                Util.v().getLocalForStackOp(listBody,
3475:                                        postTypeStack,
3476:                                        postTypeStack.topIndex() - 3),
3477:                                Util.v()
3478:                                        .getLocalForStackOp(listBody,
3479:                                                postTypeStack,
3480:                                                postTypeStack.topIndex()));
3481:
3482:                        statements.add(stmt);
3483:
3484:                        stmt = Jimple.v().newAssignStmt(
3485:                                Util.v().getLocalForStackOp(listBody,
3486:                                        postTypeStack,
3487:                                        postTypeStack.topIndex() - 4),
3488:                                Util.v().getLocalForStackOp(listBody,
3489:                                        postTypeStack,
3490:                                        postTypeStack.topIndex() - 1));
3491:
3492:                        statements.add(stmt);
3493:
3494:                        stmt = null;
3495:                    }
3496:                    break;
3497:
3498:                case ByteCode.DUP2_X2:
3499:                    if (typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2) {
3500:                        l2 = Util.v().getLocalForStackOp(listBody, typeStack,
3501:                                typeStack.topIndex() - 1);
3502:
3503:                        stmt = Jimple.v().newAssignStmt(
3504:                                Util.v().getLocalForStackOp(listBody,
3505:                                        postTypeStack,
3506:                                        postTypeStack.topIndex() - 1), l2);
3507:
3508:                        statements.add(stmt);
3509:                    } else {
3510:                        l1 = Util.v().getLocalForStackOp(listBody, typeStack,
3511:                                typeStack.topIndex());
3512:                        l2 = Util.v().getLocalForStackOp(listBody, typeStack,
3513:                                typeStack.topIndex() - 1);
3514:
3515:                        stmt = Jimple.v().newAssignStmt(
3516:                                Util.v().getLocalForStackOp(listBody,
3517:                                        postTypeStack,
3518:                                        postTypeStack.topIndex() - 1), l2);
3519:
3520:                        statements.add(stmt);
3521:
3522:                        stmt = Jimple.v().newAssignStmt(
3523:                                Util.v()
3524:                                        .getLocalForStackOp(listBody,
3525:                                                postTypeStack,
3526:                                                postTypeStack.topIndex()), l1);
3527:
3528:                        statements.add(stmt);
3529:
3530:                    }
3531:
3532:                    if (typeSize(typeStack.get(typeStack.topIndex() - 3)) == 2) {
3533:                        l4 = Util.v().getLocalForStackOp(listBody, typeStack,
3534:                                typeStack.topIndex() - 3);
3535:
3536:                        stmt = Jimple.v().newAssignStmt(
3537:                                Util.v().getLocalForStackOp(listBody,
3538:                                        postTypeStack,
3539:                                        postTypeStack.topIndex() - 3), l4);
3540:
3541:                        statements.add(stmt);
3542:                    } else {
3543:                        l4 = Util.v().getLocalForStackOp(listBody, typeStack,
3544:                                typeStack.topIndex() - 3);
3545:                        l3 = Util.v().getLocalForStackOp(listBody, typeStack,
3546:                                typeStack.topIndex() - 2);
3547:
3548:                        stmt = Jimple.v().newAssignStmt(
3549:                                Util.v().getLocalForStackOp(listBody,
3550:                                        postTypeStack,
3551:                                        postTypeStack.topIndex() - 3), l4);
3552:
3553:                        statements.add(stmt);
3554:
3555:                        stmt = Jimple.v().newAssignStmt(
3556:                                Util.v().getLocalForStackOp(listBody,
3557:                                        postTypeStack,
3558:                                        postTypeStack.topIndex() - 2), l3);
3559:
3560:                        statements.add(stmt);
3561:
3562:                    }
3563:
3564:                    if (typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2) {
3565:                        stmt = Jimple.v().newAssignStmt(
3566:                                Util.v().getLocalForStackOp(listBody,
3567:                                        postTypeStack,
3568:                                        postTypeStack.topIndex() - 5),
3569:                                Util.v().getLocalForStackOp(listBody,
3570:                                        postTypeStack,
3571:                                        postTypeStack.topIndex() - 1));
3572:
3573:                        statements.add(stmt);
3574:                    } else {
3575:                        stmt = Jimple.v().newAssignStmt(
3576:                                Util.v().getLocalForStackOp(listBody,
3577:                                        postTypeStack,
3578:                                        postTypeStack.topIndex() - 5),
3579:                                Util.v().getLocalForStackOp(listBody,
3580:                                        postTypeStack,
3581:                                        postTypeStack.topIndex() - 1));
3582:
3583:                        statements.add(stmt);
3584:
3585:                        stmt = Jimple.v().newAssignStmt(
3586:                                Util.v().getLocalForStackOp(listBody,
3587:                                        postTypeStack,
3588:                                        postTypeStack.topIndex() - 4),
3589:                                Util.v()
3590:                                        .getLocalForStackOp(listBody,
3591:                                                postTypeStack,
3592:                                                postTypeStack.topIndex()));
3593:
3594:                        statements.add(stmt);
3595:                    }
3596:                    stmt = null;
3597:                    break;
3598:
3599:                case ByteCode.SWAP: {
3600:                    Local first;
3601:
3602:                    typeStack = typeStack.push(typeStack.top());
3603:                    first = Util.v().getLocalForStackOp(listBody, typeStack,
3604:                            typeStack.topIndex());
3605:                    typeStack = typeStack.pop();
3606:                    // generation of a free temporary
3607:
3608:                    Local second = Util.v().getLocalForStackOp(listBody,
3609:                            postTypeStack, postTypeStack.topIndex());
3610:
3611:                    Local third = Util.v().getLocalForStackOp(listBody,
3612:                            postTypeStack, postTypeStack.topIndex() - 1);
3613:
3614:                    stmt = Jimple.v().newAssignStmt(first, second);
3615:                    statements.add(stmt);
3616:
3617:                    stmt = Jimple.v().newAssignStmt(second, third);
3618:                    statements.add(stmt);
3619:
3620:                    stmt = Jimple.v().newAssignStmt(third, first);
3621:                    statements.add(stmt);
3622:
3623:                    stmt = null;
3624:                    break;
3625:                }
3626:
3627:                case ByteCode.FADD:
3628:                case ByteCode.IADD:
3629:                    rhs = Jimple.v().newAddExpr(
3630:                            Util.v().getLocalForStackOp(listBody, typeStack,
3631:                                    typeStack.topIndex() - 1),
3632:                            Util.v().getLocalForStackOp(listBody, typeStack,
3633:                                    typeStack.topIndex()));
3634:
3635:                    stmt = Jimple.v().newAssignStmt(
3636:                            Util.v().getLocalForStackOp(listBody,
3637:                                    postTypeStack, postTypeStack.topIndex()),
3638:                            rhs);
3639:                    break;
3640:
3641:                case ByteCode.DADD:
3642:                case ByteCode.LADD:
3643:                    rhs = Jimple.v().newAddExpr(
3644:                            Util.v().getLocalForStackOp(listBody, typeStack,
3645:                                    typeStack.topIndex() - 3),
3646:                            Util.v().getLocalForStackOp(listBody, typeStack,
3647:                                    typeStack.topIndex() - 1));
3648:
3649:                    stmt = Jimple.v().newAssignStmt(
3650:                            Util.v().getLocalForStackOp(listBody,
3651:                                    postTypeStack, postTypeStack.topIndex()),
3652:                            rhs);
3653:                    break;
3654:
3655:                case ByteCode.FSUB:
3656:                case ByteCode.ISUB:
3657:                    rhs = Jimple.v().newSubExpr(
3658:                            Util.v().getLocalForStackOp(listBody, typeStack,
3659:                                    typeStack.topIndex() - 1),
3660:                            Util.v().getLocalForStackOp(listBody, typeStack,
3661:                                    typeStack.topIndex()));
3662:
3663:                    stmt = Jimple.v().newAssignStmt(
3664:                            Util.v().getLocalForStackOp(listBody,
3665:                                    postTypeStack, postTypeStack.topIndex()),
3666:                            rhs);
3667:                    break;
3668:
3669:                case ByteCode.DSUB:
3670:                case ByteCode.LSUB:
3671:                    rhs = Jimple.v().newSubExpr(
3672:                            Util.v().getLocalForStackOp(listBody, typeStack,
3673:                                    typeStack.topIndex() - 3),
3674:                            Util.v().getLocalForStackOp(listBody, typeStack,
3675:                                    typeStack.topIndex() - 1));
3676:
3677:                    stmt = Jimple.v().newAssignStmt(
3678:                            Util.v().getLocalForStackOp(listBody,
3679:                                    postTypeStack, postTypeStack.topIndex()),
3680:                            rhs);
3681:                    break;
3682:
3683:                case ByteCode.FMUL:
3684:                case ByteCode.IMUL:
3685:                    rhs = Jimple.v().newMulExpr(
3686:                            Util.v().getLocalForStackOp(listBody, typeStack,
3687:                                    typeStack.topIndex() - 1),
3688:                            Util.v().getLocalForStackOp(listBody, typeStack,
3689:                                    typeStack.topIndex()));
3690:
3691:                    stmt = Jimple.v().newAssignStmt(
3692:                            Util.v().getLocalForStackOp(listBody,
3693:                                    postTypeStack, postTypeStack.topIndex()),
3694:                            rhs);
3695:                    break;
3696:
3697:                case ByteCode.DMUL:
3698:                case ByteCode.LMUL:
3699:                    rhs = Jimple.v().newMulExpr(
3700:                            Util.v().getLocalForStackOp(listBody, typeStack,
3701:                                    typeStack.topIndex() - 3),
3702:                            Util.v().getLocalForStackOp(listBody, typeStack,
3703:                                    typeStack.topIndex() - 1));
3704:
3705:                    stmt = Jimple.v().newAssignStmt(
3706:                            Util.v().getLocalForStackOp(listBody,
3707:                                    postTypeStack, postTypeStack.topIndex()),
3708:                            rhs);
3709:                    break;
3710:
3711:                case ByteCode.FDIV:
3712:                case ByteCode.IDIV:
3713:                    rhs = Jimple.v().newDivExpr(
3714:                            Util.v().getLocalForStackOp(listBody, typeStack,
3715:                                    typeStack.topIndex() - 1),
3716:                            Util.v().getLocalForStackOp(listBody, typeStack,
3717:                                    typeStack.topIndex()));
3718:
3719:                    stmt = Jimple.v().newAssignStmt(
3720:                            Util.v().getLocalForStackOp(listBody,
3721:                                    postTypeStack, postTypeStack.topIndex()),
3722:                            rhs);
3723:                    break;
3724:
3725:                case ByteCode.DDIV:
3726:                case ByteCode.LDIV:
3727:                    rhs = Jimple.v().newDivExpr(
3728:                            Util.v().getLocalForStackOp(listBody, typeStack,
3729:                                    typeStack.topIndex() - 3),
3730:                            Util.v().getLocalForStackOp(listBody, typeStack,
3731:                                    typeStack.topIndex() - 1));
3732:
3733:                    stmt = Jimple.v().newAssignStmt(
3734:                            Util.v().getLocalForStackOp(listBody,
3735:                                    postTypeStack, postTypeStack.topIndex()),
3736:                            rhs);
3737:                    break;
3738:
3739:                case ByteCode.FREM:
3740:                case ByteCode.IREM:
3741:                    rhs = Jimple.v().newRemExpr(
3742:                            Util.v().getLocalForStackOp(listBody, typeStack,
3743:                                    typeStack.topIndex() - 1),
3744:                            Util.v().getLocalForStackOp(listBody, typeStack,
3745:                                    typeStack.topIndex()));
3746:
3747:                    stmt = Jimple.v().newAssignStmt(
3748:                            Util.v().getLocalForStackOp(listBody,
3749:                                    postTypeStack, postTypeStack.topIndex()),
3750:                            rhs);
3751:                    break;
3752:
3753:                case ByteCode.DREM:
3754:                case ByteCode.LREM:
3755:                    rhs = Jimple.v().newRemExpr(
3756:                            Util.v().getLocalForStackOp(listBody, typeStack,
3757:                                    typeStack.topIndex() - 3),
3758:                            Util.v().getLocalForStackOp(listBody, typeStack,
3759:                                    typeStack.topIndex() - 1));
3760:
3761:                    stmt = Jimple.v().newAssignStmt(
3762:                            Util.v().getLocalForStackOp(listBody,
3763:                                    postTypeStack, postTypeStack.topIndex()),
3764:                            rhs);
3765:                    break;
3766:
3767:                case ByteCode.INEG:
3768:                case ByteCode.LNEG:
3769:                case ByteCode.FNEG:
3770:                case ByteCode.DNEG:
3771:                    rhs = Jimple.v().newNegExpr(
3772:                            Util.v().getLocalForStackOp(listBody, typeStack,
3773:                                    typeStack.topIndex()));
3774:                    stmt = Jimple.v().newAssignStmt(
3775:                            Util.v().getLocalForStackOp(listBody,
3776:                                    postTypeStack, postTypeStack.topIndex()),
3777:                            rhs);
3778:                    break;
3779:
3780:                case ByteCode.ISHL:
3781:                    rhs = Jimple.v().newShlExpr(
3782:                            Util.v().getLocalForStackOp(listBody, typeStack,
3783:                                    typeStack.topIndex() - 1),
3784:                            Util.v().getLocalForStackOp(listBody, typeStack,
3785:                                    typeStack.topIndex()));
3786:
3787:                    stmt = Jimple.v().newAssignStmt(
3788:                            Util.v().getLocalForStackOp(listBody,
3789:                                    postTypeStack, postTypeStack.topIndex()),
3790:                            rhs);
3791:                    break;
3792:
3793:                case ByteCode.ISHR:
3794:                    rhs = Jimple.v().newShrExpr(
3795:                            Util.v().getLocalForStackOp(listBody, typeStack,
3796:                                    typeStack.topIndex() - 1),
3797:                            Util.v().getLocalForStackOp(listBody, typeStack,
3798:                                    typeStack.topIndex()));
3799:
3800:                    stmt = Jimple.v().newAssignStmt(
3801:                            Util.v().getLocalForStackOp(listBody,
3802:                                    postTypeStack, postTypeStack.topIndex()),
3803:                            rhs);
3804:                    break;
3805:
3806:                case ByteCode.IUSHR:
3807:                    rhs = Jimple.v().newUshrExpr(
3808:                            Util.v().getLocalForStackOp(listBody, typeStack,
3809:                                    typeStack.topIndex() - 1),
3810:                            Util.v().getLocalForStackOp(listBody, typeStack,
3811:                                    typeStack.topIndex()));
3812:
3813:                    stmt = Jimple.v().newAssignStmt(
3814:                            Util.v().getLocalForStackOp(listBody,
3815:                                    postTypeStack, postTypeStack.topIndex()),
3816:                            rhs);
3817:                    break;
3818:
3819:                case ByteCode.LSHL:
3820:                    rhs = Jimple.v().newShlExpr(
3821:                            Util.v().getLocalForStackOp(listBody, typeStack,
3822:                                    typeStack.topIndex() - 2),
3823:                            Util.v().getLocalForStackOp(listBody, typeStack,
3824:                                    typeStack.topIndex()));
3825:
3826:                    stmt = Jimple.v().newAssignStmt(
3827:                            Util.v().getLocalForStackOp(listBody,
3828:                                    postTypeStack, postTypeStack.topIndex()),
3829:                            rhs);
3830:                    break;
3831:
3832:                case ByteCode.LSHR:
3833:                    rhs = Jimple.v().newShrExpr(
3834:                            Util.v().getLocalForStackOp(listBody, typeStack,
3835:                                    typeStack.topIndex() - 2),
3836:                            Util.v().getLocalForStackOp(listBody, typeStack,
3837:                                    typeStack.topIndex()));
3838:
3839:                    stmt = Jimple.v().newAssignStmt(
3840:                            Util.v().getLocalForStackOp(listBody,
3841:                                    postTypeStack, postTypeStack.topIndex()),
3842:                            rhs);
3843:                    break;
3844:
3845:                case ByteCode.LUSHR:
3846:                    rhs = Jimple.v().newUshrExpr(
3847:                            Util.v().getLocalForStackOp(listBody, typeStack,
3848:                                    typeStack.topIndex() - 2),
3849:                            Util.v().getLocalForStackOp(listBody, typeStack,
3850:                                    typeStack.topIndex()));
3851:
3852:                    stmt = Jimple.v().newAssignStmt(
3853:                            Util.v().getLocalForStackOp(listBody,
3854:                                    postTypeStack, postTypeStack.topIndex()),
3855:                            rhs);
3856:                    break;
3857:
3858:                case ByteCode.IAND:
3859:                    rhs = Jimple.v().newAndExpr(
3860:                            Util.v().getLocalForStackOp(listBody, typeStack,
3861:                                    typeStack.topIndex() - 1),
3862:                            Util.v().getLocalForStackOp(listBody, typeStack,
3863:                                    typeStack.topIndex()));
3864:
3865:                    stmt = Jimple.v().newAssignStmt(
3866:                            Util.v().getLocalForStackOp(listBody,
3867:                                    postTypeStack, postTypeStack.topIndex()),
3868:                            rhs);
3869:                    break;
3870:
3871:                case ByteCode.LAND:
3872:                    rhs = Jimple.v().newAndExpr(
3873:                            Util.v().getLocalForStackOp(listBody, typeStack,
3874:                                    typeStack.topIndex() - 3),
3875:                            Util.v().getLocalForStackOp(listBody, typeStack,
3876:                                    typeStack.topIndex() - 1));
3877:
3878:                    stmt = Jimple.v().newAssignStmt(
3879:                            Util.v().getLocalForStackOp(listBody,
3880:                                    postTypeStack, postTypeStack.topIndex()),
3881:                            rhs);
3882:                    break;
3883:
3884:                case ByteCode.IOR:
3885:                    rhs = Jimple.v().newOrExpr(
3886:                            Util.v().getLocalForStackOp(listBody, typeStack,
3887:                                    typeStack.topIndex() - 1),
3888:                            Util.v().getLocalForStackOp(listBody, typeStack,
3889:                                    typeStack.topIndex()));
3890:
3891:                    stmt = Jimple.v().newAssignStmt(
3892:                            Util.v().getLocalForStackOp(listBody,
3893:                                    postTypeStack, postTypeStack.topIndex()),
3894:                            rhs);
3895:                    break;
3896:
3897:                case ByteCode.LOR:
3898:                    rhs = Jimple.v().newOrExpr(
3899:                            Util.v().getLocalForStackOp(listBody, typeStack,
3900:                                    typeStack.topIndex() - 3),
3901:                            Util.v().getLocalForStackOp(listBody, typeStack,
3902:                                    typeStack.topIndex() - 1));
3903:
3904:                    stmt = Jimple.v().newAssignStmt(
3905:                            Util.v().getLocalForStackOp(listBody,
3906:                                    postTypeStack, postTypeStack.topIndex()),
3907:                            rhs);
3908:                    break;
3909:
3910:                case ByteCode.IXOR:
3911:                    rhs = Jimple.v().newXorExpr(
3912:                            Util.v().getLocalForStackOp(listBody, typeStack,
3913:                                    typeStack.topIndex() - 1),
3914:                            Util.v().getLocalForStackOp(listBody, typeStack,
3915:                                    typeStack.topIndex()));
3916:
3917:                    stmt = Jimple.v().newAssignStmt(
3918:                            Util.v().getLocalForStackOp(listBody,
3919:                                    postTypeStack, postTypeStack.topIndex()),
3920:                            rhs);
3921:                    break;
3922:
3923:                case ByteCode.LXOR:
3924:                    rhs = Jimple.v().newXorExpr(
3925:                            Util.v().getLocalForStackOp(listBody, typeStack,
3926:                                    typeStack.topIndex() - 3),
3927:                            Util.v().getLocalForStackOp(listBody, typeStack,
3928:                                    typeStack.topIndex() - 1));
3929:
3930:                    stmt = Jimple.v().newAssignStmt(
3931:                            Util.v().getLocalForStackOp(listBody,
3932:                                    postTypeStack, postTypeStack.topIndex()),
3933:                            rhs);
3934:                    break;
3935:
3936:                case ByteCode.D2L:
3937:                case ByteCode.F2L:
3938:                case ByteCode.I2L:
3939:                    rhs = Jimple.v().newCastExpr(
3940:                            Util.v().getLocalForStackOp(listBody, typeStack,
3941:                                    typeStack.topIndex()), LongType.v());
3942:
3943:                    stmt = Jimple.v().newAssignStmt(
3944:                            Util.v().getLocalForStackOp(listBody,
3945:                                    postTypeStack, postTypeStack.topIndex()),
3946:                            rhs);
3947:                    break;
3948:
3949:                case ByteCode.D2F:
3950:                case ByteCode.L2F:
3951:                case ByteCode.I2F:
3952:                    rhs = Jimple.v().newCastExpr(
3953:                            Util.v().getLocalForStackOp(listBody, typeStack,
3954:                                    typeStack.topIndex()), FloatType.v());
3955:
3956:                    stmt = Jimple.v().newAssignStmt(
3957:                            Util.v().getLocalForStackOp(listBody,
3958:                                    postTypeStack, postTypeStack.topIndex()),
3959:                            rhs);
3960:                    break;
3961:
3962:                case ByteCode.I2D:
3963:                case ByteCode.L2D:
3964:                case ByteCode.F2D:
3965:                    rhs = Jimple.v().newCastExpr(
3966:                            Util.v().getLocalForStackOp(listBody, typeStack,
3967:                                    typeStack.topIndex()), DoubleType.v());
3968:
3969:                    stmt = Jimple.v().newAssignStmt(
3970:                            Util.v().getLocalForStackOp(listBody,
3971:                                    postTypeStack, postTypeStack.topIndex()),
3972:                            rhs);
3973:                    break;
3974:
3975:                case ByteCode.L2I:
3976:                case ByteCode.F2I:
3977:                case ByteCode.D2I:
3978:                    rhs = Jimple.v().newCastExpr(
3979:                            Util.v().getLocalForStackOp(listBody, typeStack,
3980:                                    typeStack.topIndex()), IntType.v());
3981:
3982:                    stmt = Jimple.v().newAssignStmt(
3983:                            Util.v().getLocalForStackOp(listBody,
3984:                                    postTypeStack, postTypeStack.topIndex()),
3985:                            rhs);
3986:                    break;
3987:
3988:                case ByteCode.INT2BYTE:
3989:                    rhs = Jimple.v().newCastExpr(
3990:                            Util.v().getLocalForStackOp(listBody, typeStack,
3991:                                    typeStack.topIndex()), ByteType.v());
3992:
3993:                    stmt = Jimple.v().newAssignStmt(
3994:                            Util.v().getLocalForStackOp(listBody,
3995:                                    postTypeStack, postTypeStack.topIndex()),
3996:                            rhs);
3997:                    break;
3998:
3999:                case ByteCode.INT2CHAR:
4000:                    rhs = Jimple.v().newCastExpr(
4001:                            Util.v().getLocalForStackOp(listBody, typeStack,
4002:                                    typeStack.topIndex()), CharType.v());
4003:
4004:                    stmt = Jimple.v().newAssignStmt(
4005:                            Util.v().getLocalForStackOp(listBody,
4006:                                    postTypeStack, postTypeStack.topIndex()),
4007:                            rhs);
4008:                    break;
4009:
4010:                case ByteCode.INT2SHORT:
4011:                    rhs = Jimple.v().newCastExpr(
4012:                            Util.v().getLocalForStackOp(listBody, typeStack,
4013:                                    typeStack.topIndex()), ShortType.v());
4014:
4015:                    stmt = Jimple.v().newAssignStmt(
4016:                            Util.v().getLocalForStackOp(listBody,
4017:                                    postTypeStack, postTypeStack.topIndex()),
4018:                            rhs);
4019:                    break;
4020:
4021:                case ByteCode.IFEQ:
4022:                    co = Jimple.v().newEqExpr(
4023:                            Util.v().getLocalForStackOp(listBody, typeStack,
4024:                                    typeStack.topIndex()), IntConstant.v(0));
4025:
4026:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4027:                    break;
4028:
4029:                case ByteCode.IFNULL:
4030:                    co = Jimple.v().newEqExpr(
4031:                            Util.v().getLocalForStackOp(listBody, typeStack,
4032:                                    typeStack.topIndex()), NullConstant.v());
4033:
4034:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4035:                    break;
4036:
4037:                case ByteCode.IFLT:
4038:                    co = Jimple.v().newLtExpr(
4039:                            Util.v().getLocalForStackOp(listBody, typeStack,
4040:                                    typeStack.topIndex()), IntConstant.v(0));
4041:
4042:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4043:                    break;
4044:
4045:                case ByteCode.IFLE:
4046:                    co = Jimple.v().newLeExpr(
4047:                            Util.v().getLocalForStackOp(listBody, typeStack,
4048:                                    typeStack.topIndex()), IntConstant.v(0));
4049:
4050:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4051:                    break;
4052:
4053:                case ByteCode.IFNE:
4054:                    co = Jimple.v().newNeExpr(
4055:                            Util.v().getLocalForStackOp(listBody, typeStack,
4056:                                    typeStack.topIndex()), IntConstant.v(0));
4057:
4058:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4059:                    break;
4060:
4061:                case ByteCode.IFNONNULL:
4062:                    co = Jimple.v().newNeExpr(
4063:                            Util.v().getLocalForStackOp(listBody, typeStack,
4064:                                    typeStack.topIndex()), NullConstant.v());
4065:
4066:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4067:                    break;
4068:
4069:                case ByteCode.IFGT:
4070:                    co = Jimple.v().newGtExpr(
4071:                            Util.v().getLocalForStackOp(listBody, typeStack,
4072:                                    typeStack.topIndex()), IntConstant.v(0));
4073:
4074:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4075:                    break;
4076:
4077:                case ByteCode.IFGE:
4078:                    co = Jimple.v().newGeExpr(
4079:                            Util.v().getLocalForStackOp(listBody, typeStack,
4080:                                    typeStack.topIndex()), IntConstant.v(0));
4081:
4082:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4083:                    break;
4084:
4085:                case ByteCode.IF_ICMPEQ:
4086:                    co = Jimple.v().newEqExpr(
4087:                            Util.v().getLocalForStackOp(listBody, typeStack,
4088:                                    typeStack.topIndex() - 1),
4089:                            Util.v().getLocalForStackOp(listBody, typeStack,
4090:                                    typeStack.topIndex()));
4091:
4092:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4093:                    break;
4094:
4095:                case ByteCode.IF_ICMPLT:
4096:                    co = Jimple.v().newLtExpr(
4097:                            Util.v().getLocalForStackOp(listBody, typeStack,
4098:                                    typeStack.topIndex() - 1),
4099:                            Util.v().getLocalForStackOp(listBody, typeStack,
4100:                                    typeStack.topIndex()));
4101:
4102:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4103:                    break;
4104:
4105:                case ByteCode.IF_ICMPLE:
4106:                    co = Jimple.v().newLeExpr(
4107:                            Util.v().getLocalForStackOp(listBody, typeStack,
4108:                                    typeStack.topIndex() - 1),
4109:                            Util.v().getLocalForStackOp(listBody, typeStack,
4110:                                    typeStack.topIndex()));
4111:
4112:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4113:                    break;
4114:
4115:                case ByteCode.IF_ICMPNE:
4116:                    co = Jimple.v().newNeExpr(
4117:                            Util.v().getLocalForStackOp(listBody, typeStack,
4118:                                    typeStack.topIndex() - 1),
4119:                            Util.v().getLocalForStackOp(listBody, typeStack,
4120:                                    typeStack.topIndex()));
4121:
4122:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4123:                    break;
4124:
4125:                case ByteCode.IF_ICMPGT:
4126:                    co = Jimple.v().newGtExpr(
4127:                            Util.v().getLocalForStackOp(listBody, typeStack,
4128:                                    typeStack.topIndex() - 1),
4129:                            Util.v().getLocalForStackOp(listBody, typeStack,
4130:                                    typeStack.topIndex()));
4131:
4132:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4133:                    break;
4134:
4135:                case ByteCode.IF_ICMPGE:
4136:                    co = Jimple.v().newGeExpr(
4137:                            Util.v().getLocalForStackOp(listBody, typeStack,
4138:                                    typeStack.topIndex() - 1),
4139:                            Util.v().getLocalForStackOp(listBody, typeStack,
4140:                                    typeStack.topIndex()));
4141:
4142:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4143:                    break;
4144:
4145:                case ByteCode.LCMP:
4146:                    rhs = Jimple.v().newCmpExpr(
4147:                            Util.v().getLocalForStackOp(listBody, typeStack,
4148:                                    typeStack.topIndex() - 3),
4149:                            Util.v().getLocalForStackOp(listBody, typeStack,
4150:                                    typeStack.topIndex() - 1));
4151:
4152:                    stmt = Jimple.v().newAssignStmt(
4153:                            Util.v().getLocalForStackOp(listBody,
4154:                                    postTypeStack, postTypeStack.topIndex()),
4155:                            rhs);
4156:                    break;
4157:
4158:                case ByteCode.FCMPL:
4159:                    rhs = Jimple.v().newCmplExpr(
4160:                            Util.v().getLocalForStackOp(listBody, typeStack,
4161:                                    typeStack.topIndex() - 1),
4162:                            Util.v().getLocalForStackOp(listBody, typeStack,
4163:                                    typeStack.topIndex()));
4164:
4165:                    stmt = Jimple.v().newAssignStmt(
4166:                            Util.v().getLocalForStackOp(listBody,
4167:                                    postTypeStack, postTypeStack.topIndex()),
4168:                            rhs);
4169:                    break;
4170:
4171:                case ByteCode.FCMPG:
4172:                    rhs = Jimple.v().newCmpgExpr(
4173:                            Util.v().getLocalForStackOp(listBody, typeStack,
4174:                                    typeStack.topIndex() - 1),
4175:                            Util.v().getLocalForStackOp(listBody, typeStack,
4176:                                    typeStack.topIndex()));
4177:
4178:                    stmt = Jimple.v().newAssignStmt(
4179:                            Util.v().getLocalForStackOp(listBody,
4180:                                    postTypeStack, postTypeStack.topIndex()),
4181:                            rhs);
4182:                    break;
4183:
4184:                case ByteCode.DCMPL:
4185:                    rhs = Jimple.v().newCmplExpr(
4186:                            Util.v().getLocalForStackOp(listBody, typeStack,
4187:                                    typeStack.topIndex() - 3),
4188:                            Util.v().getLocalForStackOp(listBody, typeStack,
4189:                                    typeStack.topIndex() - 1));
4190:
4191:                    stmt = Jimple.v().newAssignStmt(
4192:                            Util.v().getLocalForStackOp(listBody,
4193:                                    postTypeStack, postTypeStack.topIndex()),
4194:                            rhs);
4195:                    break;
4196:
4197:                case ByteCode.DCMPG:
4198:                    rhs = Jimple.v().newCmpgExpr(
4199:                            Util.v().getLocalForStackOp(listBody, typeStack,
4200:                                    typeStack.topIndex() - 3),
4201:                            Util.v().getLocalForStackOp(listBody, typeStack,
4202:                                    typeStack.topIndex() - 1));
4203:
4204:                    stmt = Jimple.v().newAssignStmt(
4205:                            Util.v().getLocalForStackOp(listBody,
4206:                                    postTypeStack, postTypeStack.topIndex()),
4207:                            rhs);
4208:                    break;
4209:
4210:                case ByteCode.IF_ACMPEQ:
4211:                    co = Jimple.v().newEqExpr(
4212:                            Util.v().getLocalForStackOp(listBody, typeStack,
4213:                                    typeStack.topIndex() - 1),
4214:                            Util.v().getLocalForStackOp(listBody, typeStack,
4215:                                    typeStack.topIndex()));
4216:
4217:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4218:                    break;
4219:
4220:                case ByteCode.IF_ACMPNE:
4221:                    co = Jimple.v().newNeExpr(
4222:                            Util.v().getLocalForStackOp(listBody, typeStack,
4223:                                    typeStack.topIndex() - 1),
4224:                            Util.v().getLocalForStackOp(listBody, typeStack,
4225:                                    typeStack.topIndex()));
4226:
4227:                    stmt = Jimple.v().newIfStmt(co, new FutureStmt());
4228:                    break;
4229:
4230:                case ByteCode.GOTO:
4231:                    stmt = Jimple.v().newGotoStmt(new FutureStmt());
4232:                    break;
4233:
4234:                case ByteCode.GOTO_W:
4235:                    stmt = Jimple.v().newGotoStmt(new FutureStmt());
4236:                    break;
4237:                /*
4238:                 case ByteCode.JSR:
4239:                 case ByteCode.JSR_W:
4240:                 {
4241:                 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack,
4242:                 postTypeStack.topIndex()), Jimple.v().newNextNextStmtRef());
4243:
4244:                 statements.add(stmt);
4245:
4246:                 stmt = Jimple.v().newGotoStmt(new FutureStmt());
4247:                 statements.add(stmt);
4248:
4249:                 stmt = null;
4250:                 break;
4251:                 }
4252:                 */
4253:
4254:                case ByteCode.RET: {
4255:                    Local local = Util.v().getLocalForIndex(listBody,
4256:                            ((Instruction_Ret) ins).arg_b);
4257:
4258:                    stmt = Jimple.v().newRetStmt(local);
4259:                    break;
4260:                }
4261:
4262:                case ByteCode.RET_W: {
4263:                    Local local = Util.v().getLocalForIndex(listBody,
4264:                            ((Instruction_Ret_w) ins).arg_i);
4265:
4266:                    stmt = Jimple.v().newRetStmt(local);
4267:                    break;
4268:                }
4269:
4270:                case ByteCode.RETURN:
4271:                    stmt = Jimple.v().newReturnVoidStmt();
4272:                    break;
4273:
4274:                case ByteCode.LRETURN:
4275:                case ByteCode.DRETURN:
4276:                case ByteCode.IRETURN:
4277:                case ByteCode.FRETURN:
4278:                case ByteCode.ARETURN:
4279:                    stmt = Jimple.v().newReturnStmt(
4280:                            Util.v().getLocalForStackOp(listBody, typeStack,
4281:                                    typeStack.topIndex()));
4282:                    break;
4283:
4284:                case ByteCode.BREAKPOINT:
4285:                    stmt = Jimple.v().newBreakpointStmt();
4286:                    break;
4287:
4288:                case ByteCode.TABLESWITCH: {
4289:                    int lowIndex = ((Instruction_Tableswitch) ins).low, highIndex = ((Instruction_Tableswitch) ins).high;
4290:
4291:                    stmt = Jimple.v().newTableSwitchStmt(
4292:                            Util.v().getLocalForStackOp(listBody, typeStack,
4293:                                    typeStack.topIndex()),
4294:                            lowIndex,
4295:                            highIndex,
4296:                            Arrays.asList(new FutureStmt[highIndex - lowIndex
4297:                                    + 1]), new FutureStmt());
4298:                    break;
4299:                }
4300:
4301:                case ByteCode.LOOKUPSWITCH: {
4302:                    List matches = new ArrayList();
4303:                    int npairs = ((Instruction_Lookupswitch) ins).npairs;
4304:
4305:                    for (int j = 0; j < npairs; j++)
4306:                        matches
4307:                                .add(IntConstant
4308:                                        .v(((Instruction_Lookupswitch) ins).match_offsets[j * 2]));
4309:
4310:                    stmt = Jimple.v().newLookupSwitchStmt(
4311:                            Util.v().getLocalForStackOp(listBody, typeStack,
4312:                                    typeStack.topIndex()), matches,
4313:                            Arrays.asList(new FutureStmt[npairs]),
4314:                            new FutureStmt());
4315:                    break;
4316:                }
4317:
4318:                case ByteCode.PUTFIELD: {
4319:                    CONSTANT_Fieldref_info fieldInfo = (CONSTANT_Fieldref_info) constant_pool[((Instruction_Putfield) ins).arg_i];
4320:
4321:                    CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
4322:
4323:                    String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index]))
4324:                            .convert();
4325:                    className = className.replace('/', '.');
4326:
4327:                    CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
4328:
4329:                    String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index]))
4330:                            .convert();
4331:                    String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index]))
4332:                            .convert();
4333:
4334:                    Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(
4335:                            fieldDescriptor);
4336:
4337:                    SootClass bclass = cm.getSootClass(className);
4338:
4339:                    SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass,
4340:                            fieldName, fieldType, false);
4341:
4342:                    InstanceFieldRef fr = Jimple.v().newInstanceFieldRef(
4343:                            Util.v().getLocalForStackOp(
4344:                                    listBody,
4345:                                    typeStack,
4346:                                    typeStack.topIndex()
4347:                                            - typeSize(typeStack.top())),
4348:                            fieldRef);
4349:
4350:                    rvalue = Util.v().getLocalForStackOp(listBody, typeStack,
4351:                            typeStack.topIndex());
4352:                    stmt = Jimple.v().newAssignStmt(fr, rvalue);
4353:                    break;
4354:                }
4355:
4356:                case ByteCode.GETFIELD: {
4357:                    InstanceFieldRef fr = null;
4358:
4359:                    CONSTANT_Fieldref_info fieldInfo = (CONSTANT_Fieldref_info) constant_pool[((Instruction_Getfield) ins).arg_i];
4360:
4361:                    CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
4362:
4363:                    String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index]))
4364:                            .convert();
4365:                    className = className.replace('/', '.');
4366:
4367:                    CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
4368:
4369:                    String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index]))
4370:                            .convert();
4371:                    String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index]))
4372:                            .convert();
4373:
4374:                    if (className.charAt(0) == '[')
4375:                        className = "java.lang.Object";
4376:
4377:                    SootClass bclass = cm.getSootClass(className);
4378:
4379:                    Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(
4380:                            fieldDescriptor);
4381:                    SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass,
4382:                            fieldName, fieldType, false);
4383:
4384:                    fr = Jimple.v().newInstanceFieldRef(
4385:                            Util.v().getLocalForStackOp(listBody, typeStack,
4386:                                    typeStack.topIndex()), fieldRef);
4387:
4388:                    stmt = Jimple.v().newAssignStmt(
4389:                            Util.v().getLocalForStackOp(listBody,
4390:                                    postTypeStack, postTypeStack.topIndex()),
4391:                            fr);
4392:                    break;
4393:                }
4394:
4395:                case ByteCode.PUTSTATIC: {
4396:                    StaticFieldRef fr = null;
4397:
4398:                    CONSTANT_Fieldref_info fieldInfo = (CONSTANT_Fieldref_info) constant_pool[((Instruction_Putstatic) ins).arg_i];
4399:
4400:                    CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
4401:
4402:                    String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index]))
4403:                            .convert();
4404:                    className = className.replace('/', '.');
4405:
4406:                    CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
4407:
4408:                    String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index]))
4409:                            .convert();
4410:                    String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index]))
4411:                            .convert();
4412:
4413:                    Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(
4414:                            fieldDescriptor);
4415:
4416:                    SootClass bclass = cm.getSootClass(className);
4417:                    SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass,
4418:                            fieldName, fieldType, true);
4419:
4420:                    fr = Jimple.v().newStaticFieldRef(fieldRef);
4421:
4422:                    stmt = Jimple.v().newAssignStmt(
4423:                            fr,
4424:                            Util.v().getLocalForStackOp(listBody, typeStack,
4425:                                    typeStack.topIndex()));
4426:                    break;
4427:                }
4428:
4429:                case ByteCode.GETSTATIC: {
4430:                    StaticFieldRef fr = null;
4431:
4432:                    CONSTANT_Fieldref_info fieldInfo = (CONSTANT_Fieldref_info) constant_pool[((Instruction_Getstatic) ins).arg_i];
4433:
4434:                    CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
4435:
4436:                    String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index]))
4437:                            .convert();
4438:                    className = className.replace('/', '.');
4439:
4440:                    CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
4441:
4442:                    String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index]))
4443:                            .convert();
4444:                    String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index]))
4445:                            .convert();
4446:
4447:                    Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(
4448:                            fieldDescriptor);
4449:
4450:                    SootClass bclass = cm.getSootClass(className);
4451:                    SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass,
4452:                            fieldName, fieldType, true);
4453:
4454:                    fr = Jimple.v().newStaticFieldRef(fieldRef);
4455:
4456:                    stmt = Jimple.v().newAssignStmt(
4457:                            Util.v().getLocalForStackOp(listBody,
4458:                                    postTypeStack, postTypeStack.topIndex()),
4459:                            fr);
4460:                    break;
4461:                }
4462:
4463:                case ByteCode.INVOKEVIRTUAL: {
4464:                    Instruction_Invokevirtual iv = (Instruction_Invokevirtual) ins;
4465:                    args = cp_info.countParams(constant_pool, iv.arg_i);
4466:
4467:                    SootMethodRef methodRef = null;
4468:
4469:                    CONSTANT_Methodref_info methodInfo = (CONSTANT_Methodref_info) constant_pool[iv.arg_i];
4470:
4471:                    CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[methodInfo.class_index];
4472:
4473:                    String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index]))
4474:                            .convert();
4475:                    className = className.replace('/', '.');
4476:
4477:                    CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index];
4478:
4479:                    String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index]))
4480:                            .convert();
4481:                    String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index]))
4482:                            .convert();
4483:
4484:                    if (className.charAt(0) == '[')
4485:                        className = "java.lang.Object";
4486:
4487:                    SootClass bclass = cm.getSootClass(className);
4488:
4489:                    List parameterTypes;
4490:                    Type returnType;
4491:
4492:                    // Generate parameters & returnType & parameterTypes
4493:                    {
4494:                        Type[] types = Util.v()
4495:                                .jimpleTypesOfFieldOrMethodDescriptor(
4496:                                        methodDescriptor);
4497:
4498:                        parameterTypes = new ArrayList();
4499:
4500:                        for (int k = 0; k < types.length - 1; k++) {
4501:                            parameterTypes.add(types[k]);
4502:                        }
4503:
4504:                        returnType = types[types.length - 1];
4505:                    }
4506:
4507:                    methodRef = Scene.v().makeMethodRef(bclass, methodName,
4508:                            parameterTypes, returnType, false);
4509:
4510:                    // build array of parameters
4511:                    params = new Value[args];
4512:                    for (int j = args - 1; j >= 0; j--) {
4513:                        params[j] = Util.v().getLocalForStackOp(listBody,
4514:                                typeStack, typeStack.topIndex());
4515:
4516:                        if (typeSize(typeStack.top()) == 2) {
4517:                            typeStack = typeStack.pop();
4518:                            typeStack = typeStack.pop();
4519:                        } else
4520:                            typeStack = typeStack.pop();
4521:                    }
4522:
4523:                    rvalue = Jimple.v().newVirtualInvokeExpr(
4524:                            Util.v().getLocalForStackOp(listBody, typeStack,
4525:                                    typeStack.topIndex()), methodRef,
4526:                            Arrays.asList(params));
4527:
4528:                    if (!returnType.equals(VoidType.v())) {
4529:                        stmt = Jimple.v().newAssignStmt(
4530:                                Util.v()
4531:                                        .getLocalForStackOp(listBody,
4532:                                                postTypeStack,
4533:                                                postTypeStack.topIndex()),
4534:                                rvalue);
4535:                    } else
4536:                        stmt = Jimple.v().newInvokeStmt(rvalue);
4537:                    break;
4538:                }
4539:
4540:                case ByteCode.INVOKENONVIRTUAL: {
4541:                    Instruction_Invokenonvirtual iv = (Instruction_Invokenonvirtual) ins;
4542:                    args = cp_info.countParams(constant_pool, iv.arg_i);
4543:
4544:                    SootMethodRef methodRef = null;
4545:
4546:                    CONSTANT_Methodref_info methodInfo = (CONSTANT_Methodref_info) constant_pool[iv.arg_i];
4547:
4548:                    CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[methodInfo.class_index];
4549:
4550:                    String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index]))
4551:                            .convert();
4552:                    className = className.replace('/', '.');
4553:
4554:                    CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index];
4555:
4556:                    String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index]))
4557:                            .convert();
4558:                    String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index]))
4559:                            .convert();
4560:
4561:                    SootClass bclass = cm.getSootClass(className);
4562:
4563:                    List parameterTypes;
4564:                    Type returnType;
4565:
4566:                    // Generate parameters & returnType & parameterTypes
4567:                    {
4568:                        Type[] types = Util.v()
4569:                                .jimpleTypesOfFieldOrMethodDescriptor(
4570:                                        methodDescriptor);
4571:
4572:                        parameterTypes = new ArrayList();
4573:
4574:                        for (int k = 0; k < types.length - 1; k++) {
4575:                            parameterTypes.add(types[k]);
4576:                        }
4577:
4578:                        returnType = types[types.length - 1];
4579:                    }
4580:
4581:                    methodRef = Scene.v().makeMethodRef(bclass, methodName,
4582:                            parameterTypes, returnType, false);
4583:
4584:                    // build array of parameters
4585:                    params = new Value[args];
4586:                    for (int j = args - 1; j >= 0; j--) {
4587:                        params[j] = Util.v().getLocalForStackOp(listBody,
4588:                                typeStack, typeStack.topIndex());
4589:
4590:                        if (typeSize(typeStack.top()) == 2) {
4591:                            typeStack = typeStack.pop();
4592:                            typeStack = typeStack.pop();
4593:                        } else
4594:                            typeStack = typeStack.pop();
4595:                    }
4596:
4597:                    rvalue = Jimple.v().newSpecialInvokeExpr(
4598:                            Util.v().getLocalForStackOp(listBody, typeStack,
4599:                                    typeStack.topIndex()), methodRef,
4600:                            Arrays.asList(params));
4601:
4602:                    if (!returnType.equals(VoidType.v())) {
4603:                        stmt = Jimple.v().newAssignStmt(
4604:                                Util.v()
4605:                                        .getLocalForStackOp(listBody,
4606:                                                postTypeStack,
4607:                                                postTypeStack.topIndex()),
4608:                                rvalue);
4609:                    } else
4610:                        stmt = Jimple.v().newInvokeStmt(rvalue);
4611:                    break;
4612:                }
4613:
4614:                case ByteCode.INVOKESTATIC: {
4615:                    Instruction_Invokestatic is = (Instruction_Invokestatic) ins;
4616:                    args = cp_info.countParams(constant_pool, is.arg_i);
4617:
4618:                    SootMethodRef methodRef = null;
4619:
4620:                    CONSTANT_Methodref_info methodInfo = (CONSTANT_Methodref_info) constant_pool[is.arg_i];
4621:
4622:                    CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[methodInfo.class_index];
4623:
4624:                    String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index]))
4625:                            .convert();
4626:                    className = className.replace('/', '.');
4627:
4628:                    CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index];
4629:
4630:                    String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index]))
4631:                            .convert();
4632:                    String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index]))
4633:                            .convert();
4634:
4635:                    if (className.charAt(0) == '[')
4636:                        className = "java.lang.Object";
4637:
4638:                    SootClass bclass = cm.getSootClass(className);
4639:
4640:                    List parameterTypes;
4641:                    Type returnType;
4642:
4643:                    // Generate parameters & returnType & parameterTypes
4644:                    {
4645:                        Type[] types = Util.v()
4646:                                .jimpleTypesOfFieldOrMethodDescriptor(
4647:                                        methodDescriptor);
4648:
4649:                        parameterTypes = new ArrayList();
4650:
4651:                        for (int k = 0; k < types.length - 1; k++) {
4652:                            parameterTypes.add(types[k]);
4653:                        }
4654:
4655:                        returnType = types[types.length - 1];
4656:                    }
4657:
4658:                    methodRef = Scene.v().makeMethodRef(bclass, methodName,
4659:                            parameterTypes, returnType, true);
4660:
4661:                    // build Vector of parameters
4662:                    params = new Value[args];
4663:                    for (int j = args - 1; j >= 0; j--) {
4664:                        /* G.v().out.println("BeforeTypeStack");
4665:                        typeStack.print(G.v().out);
4666:
4667:                        G.v().out.println("AfterTypeStack");
4668:                        postTypeStack.print(G.v().out);
4669:                         */
4670:
4671:                        params[j] = Util.v().getLocalForStackOp(listBody,
4672:                                typeStack, typeStack.topIndex());
4673:
4674:                        if (typeSize(typeStack.top()) == 2) {
4675:                            typeStack = typeStack.pop();
4676:                            typeStack = typeStack.pop();
4677:                        } else
4678:                            typeStack = typeStack.pop();
4679:                    }
4680:
4681:                    rvalue = Jimple.v().newStaticInvokeExpr(methodRef,
4682:                            Arrays.asList(params));
4683:
4684:                    if (!returnType.equals(VoidType.v())) {
4685:                        stmt = Jimple.v().newAssignStmt(
4686:                                Util.v()
4687:                                        .getLocalForStackOp(listBody,
4688:                                                postTypeStack,
4689:                                                postTypeStack.topIndex()),
4690:                                rvalue);
4691:                    } else
4692:                        stmt = Jimple.v().newInvokeStmt(rvalue);
4693:
4694:                    break;
4695:                }
4696:
4697:                case ByteCode.INVOKEINTERFACE: {
4698:                    Instruction_Invokeinterface ii = (Instruction_Invokeinterface) ins;
4699:                    args = cp_info.countParams(constant_pool, ii.arg_i);
4700:
4701:                    SootMethodRef methodRef = null;
4702:
4703:                    CONSTANT_InterfaceMethodref_info methodInfo = (CONSTANT_InterfaceMethodref_info) constant_pool[ii.arg_i];
4704:
4705:                    CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[methodInfo.class_index];
4706:
4707:                    String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index]))
4708:                            .convert();
4709:                    className = className.replace('/', '.');
4710:
4711:                    CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index];
4712:
4713:                    String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index]))
4714:                            .convert();
4715:                    String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index]))
4716:                            .convert();
4717:
4718:                    if (className.charAt(0) == '[')
4719:                        className = "java.lang.Object";
4720:
4721:                    SootClass bclass = cm.getSootClass(className);
4722:
4723:                    List parameterTypes;
4724:                    Type returnType;
4725:
4726:                    // Generate parameters & returnType & parameterTypes
4727:                    {
4728:                        Type[] types = Util.v()
4729:                                .jimpleTypesOfFieldOrMethodDescriptor(
4730:                                        methodDescriptor);
4731:
4732:                        parameterTypes = new ArrayList();
4733:
4734:                        for (int k = 0; k < types.length - 1; k++) {
4735:                            parameterTypes.add(types[k]);
4736:                        }
4737:
4738:                        returnType = types[types.length - 1];
4739:                    }
4740:
4741:                    methodRef = Scene.v().makeMethodRef(bclass, methodName,
4742:                            parameterTypes, returnType, false);
4743:
4744:                    // build Vector of parameters
4745:                    params = new Value[args];
4746:                    for (int j = args - 1; j >= 0; j--) {
4747:                        params[j] = Util.v().getLocalForStackOp(listBody,
4748:                                typeStack, typeStack.topIndex());
4749:
4750:                        if (typeSize(typeStack.top()) == 2) {
4751:                            typeStack = typeStack.pop();
4752:                            typeStack = typeStack.pop();
4753:                        } else
4754:                            typeStack = typeStack.pop();
4755:                    }
4756:
4757:                    rvalue = Jimple.v().newInterfaceInvokeExpr(
4758:                            Util.v().getLocalForStackOp(listBody, typeStack,
4759:                                    typeStack.topIndex()), methodRef,
4760:                            Arrays.asList(params));
4761:
4762:                    if (!returnType.equals(VoidType.v())) {
4763:                        stmt = Jimple.v().newAssignStmt(
4764:                                Util.v()
4765:                                        .getLocalForStackOp(listBody,
4766:                                                postTypeStack,
4767:                                                postTypeStack.topIndex()),
4768:                                rvalue);
4769:                    } else
4770:                        stmt = Jimple.v().newInvokeStmt(rvalue);
4771:                    break;
4772:                }
4773:
4774:                case ByteCode.ATHROW:
4775:                    stmt = Jimple.v().newThrowStmt(
4776:                            Util.v().getLocalForStackOp(listBody, typeStack,
4777:                                    typeStack.topIndex()));
4778:                    break;
4779:
4780:                case ByteCode.NEW: {
4781:                    SootClass bclass = cm.getSootClass(getClassName(
4782:                            constant_pool, ((Instruction_New) ins).arg_i));
4783:
4784:                    stmt = Jimple.v().newAssignStmt(
4785:                            Util.v().getLocalForStackOp(listBody,
4786:                                    postTypeStack, postTypeStack.topIndex()),
4787:                            Jimple.v().newNewExpr(RefType.v(bclass.getName())));
4788:                    break;
4789:                }
4790:
4791:                case ByteCode.CHECKCAST: {
4792:                    String className = getClassName(constant_pool,
4793:                            ((Instruction_Checkcast) ins).arg_i);
4794:
4795:                    Type castType;
4796:
4797:                    if (className.startsWith("["))
4798:                        castType = Util.v().jimpleTypeOfFieldDescriptor(
4799:                                getClassName(constant_pool,
4800:                                        ((Instruction_Checkcast) ins).arg_i));
4801:                    else
4802:                        castType = RefType.v(className);
4803:
4804:                    rhs = Jimple.v().newCastExpr(
4805:                            Util.v().getLocalForStackOp(listBody, typeStack,
4806:                                    typeStack.topIndex()), castType);
4807:
4808:                    stmt = Jimple.v().newAssignStmt(
4809:                            Util.v().getLocalForStackOp(listBody,
4810:                                    postTypeStack, postTypeStack.topIndex()),
4811:                            rhs);
4812:                    break;
4813:                }
4814:
4815:                case ByteCode.INSTANCEOF: {
4816:                    Type checkType;
4817:
4818:                    String className = getClassName(constant_pool,
4819:                            ((Instruction_Instanceof) ins).arg_i);
4820:
4821:                    if (className.startsWith("["))
4822:                        checkType = Util.v().jimpleTypeOfFieldDescriptor(
4823:                                getClassName(constant_pool,
4824:                                        ((Instruction_Instanceof) ins).arg_i));
4825:                    else
4826:                        checkType = RefType.v(className);
4827:
4828:                    rhs = Jimple.v().newInstanceOfExpr(
4829:                            Util.v().getLocalForStackOp(listBody, typeStack,
4830:                                    typeStack.topIndex()), checkType);
4831:
4832:                    stmt = Jimple.v().newAssignStmt(
4833:                            Util.v().getLocalForStackOp(listBody,
4834:                                    postTypeStack, postTypeStack.topIndex()),
4835:                            rhs);
4836:                    break;
4837:                }
4838:
4839:                case ByteCode.MONITORENTER:
4840:                    stmt = Jimple.v().newEnterMonitorStmt(
4841:                            Util.v().getLocalForStackOp(listBody, typeStack,
4842:                                    typeStack.topIndex()));
4843:                    break;
4844:                case ByteCode.MONITOREXIT:
4845:                    stmt = Jimple.v().newExitMonitorStmt(
4846:                            Util.v().getLocalForStackOp(listBody, typeStack,
4847:                                    typeStack.topIndex()));
4848:                    break;
4849:
4850:                default:
4851:                    throw new RuntimeException(
4852:                            "Unrecognized bytecode instruction: " + x);
4853:                }
4854:
4855:                if (stmt != null) {
4856:                    if (Options.v().keep_offset()) {
4857:                        stmt.addTag(new BytecodeOffsetTag(ins.label));
4858:                    }
4859:                    statements.add(stmt);
4860:                }
4861:            }
4862:
4863:            Type jimpleTypeOfAtype(int atype) {
4864:                switch (atype) {
4865:                case 4:
4866:                    return BooleanType.v();
4867:
4868:                case 5:
4869:                    return CharType.v();
4870:
4871:                case 6:
4872:                    return FloatType.v();
4873:
4874:                case 7:
4875:                    return DoubleType.v();
4876:
4877:                case 8:
4878:                    return ByteType.v();
4879:
4880:                case 9:
4881:                    return ShortType.v();
4882:
4883:                case 10:
4884:                    return IntType.v();
4885:
4886:                case 11:
4887:                    return LongType.v();
4888:
4889:                default:
4890:                    throw new RuntimeException(
4891:                            "Undefined 'atype' in NEWARRAY byte instruction");
4892:                }
4893:            }
4894:
4895:            int typeSize(Type type) {
4896:                if (type.equals(LongType.v()) || type.equals(DoubleType.v())
4897:                        || type.equals(Long2ndHalfType.v())
4898:                        || type.equals(Double2ndHalfType.v())) {
4899:                    return 2;
4900:                } else
4901:                    return 1;
4902:            }
4903:        }
4904:
4905:        class OutFlow {
4906:            TypeStack typeStack;
4907:
4908:            OutFlow(TypeStack typeStack) {
4909:                this.typeStack = typeStack;
4910:            }
4911:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.