Source Code Cross Referenced for MethodInfo.java in  » Code-Analyzer » javapathfinder » gov » nasa » jpf » jvm » 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 » javapathfinder » gov.nasa.jpf.jvm 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        //
002:        // Copyright (C) 2005 United States Government as represented by the
003:        // Administrator of the National Aeronautics and Space Administration
004:        // (NASA).  All Rights Reserved.
005:        // 
006:        // This software is distributed under the NASA Open Source Agreement
007:        // (NOSA), version 1.3.  The NOSA has been approved by the Open Source
008:        // Initiative.  See the file NOSA-1.3-JPF at the top of the distribution
009:        // directory tree for the complete NOSA document.
010:        // 
011:        // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
012:        // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
013:        // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
014:        // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
015:        // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
016:        // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
017:        // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
018:        //
019:        package gov.nasa.jpf.jvm;
020:
021:        import gov.nasa.jpf.JPFException;
022:        import gov.nasa.jpf.jvm.bytecode.Instruction;
023:        import gov.nasa.jpf.util.Debug;
024:
025:        import org.apache.bcel.Constants;
026:        import org.apache.bcel.classfile.Code;
027:        import org.apache.bcel.classfile.CodeException;
028:        import org.apache.bcel.classfile.ConstantPool;
029:        import org.apache.bcel.classfile.LineNumberTable;
030:        import org.apache.bcel.classfile.LocalVariable;
031:        import org.apache.bcel.classfile.LocalVariableTable;
032:        import org.apache.bcel.classfile.Method;
033:        import org.apache.bcel.generic.InstructionHandle;
034:        import org.apache.bcel.generic.InstructionList;
035:        import gov.nasa.jpf.jvm.bytecode.RETURN;
036:        import gov.nasa.jpf.jvm.bytecode.InvokeInstruction;
037:        import gov.nasa.jpf.jvm.bytecode.INVOKESTATIC;
038:        import gov.nasa.jpf.jvm.bytecode.INVOKESPECIAL;
039:        import gov.nasa.jpf.jvm.bytecode.INVOKEVIRTUAL;
040:
041:        /**
042:         * information associated with a method. Each method in JPF
043:         * is represented by a MethodInfo object
044:         */
045:        public class MethodInfo implements  Cloneable {
046:            /**
047:             * Used to warn about local variable information.
048:             */
049:            protected static boolean warnedLocalInfo = false;
050:            static final int MJI_NONE = 0;
051:            static final int MJI_NATIVE = 0x1;
052:            static final int MJI_NONDETERMINISTIC = 0x2;
053:            static final int MJI_COND_DETERMINISTIC = 0x4;
054:            static final int MJI_COND_EXECUTABLE = 0x8;
055:
056:            /**
057:             * scheduling relevance (used for on-the-fly POR)
058:             */
059:            public static final int SR_NEVER = 0; // never relevant, excl. sync blocks in body
060:            public static final int SR_ALWAYS = 0x1; // always relevant
061:            public static final int SR_RUNNABLES = 0x2; // only relevant if there are other runnables
062:            public static final int SR_SYNC = 0x4; // only relevant if top lock level
063:
064:            public static final int SR_NEVERBODY = 0x8; // never relevant, incl. sync blocks in body
065:
066:            /**
067:             * Name of the method.
068:             */
069:            protected String name;
070:
071:            /**
072:             * Signature of the method.
073:             */
074:            protected String signature;
075:
076:            /**
077:             * Class the method belongs to.
078:             */
079:            protected ClassInfo ci;
080:
081:            /**
082:             * Instructions associated with the method.
083:             */
084:            protected Instruction[] code;
085:
086:            /**
087:             * Exception handlers.
088:             */
089:            protected ExceptionHandler[] exceptions;
090:
091:            /**
092:             * Table used for line numbers.
093:             */
094:            protected int[] lineNumbers;
095:
096:            /**
097:             * Local variables names.
098:             */
099:            protected String[] localVariableNames;
100:
101:            /**
102:             * Local variables types.
103:             */
104:            protected String[] localVariableTypes;
105:
106:            /**
107:             * Static method.
108:             */
109:            protected boolean isStatic;
110:
111:            /**
112:             * Synchronized method.
113:             */
114:            protected boolean isSynchronized;
115:
116:            /**
117:             * that's our own attribute - execute this method atomically
118:             */
119:            protected boolean isAtomic;
120:
121:            /**
122:             * Native method.
123:             */
124:            protected boolean isNative;
125:
126:            /**
127:             * is this a scheduling relevant method (step boundary)
128:             */
129:            protected int schedulingRelevance;
130:
131:            /**
132:             * Maximum number of local variables.
133:             */
134:            protected int maxLocals;
135:
136:            /**
137:             * Maximum number of elements on the stack.
138:             */
139:            protected int maxStack;
140:
141:            // <2do> pcm - turn this into a derived class, it's only required for MJI methods
142:
143:            /**
144:             * the number of stack slots for the arguments (incl. 'this'), lazy eval
145:             */
146:            private int argSize = -1;
147:
148:            /**
149:             * number of arguments (excl. 'this'), lazy eval
150:             */
151:            private int nArgs = -1;
152:
153:            /**
154:             * what return type do we have (again, lazy evaluated)
155:             */
156:            private byte returnType = -1;
157:
158:            /**
159:             * used for native method parameter conversion (lazy evaluated)
160:             */
161:            private byte[] argTypes = null;
162:
163:            /**
164:             * the various MJI method attrs (we don't want to burn 12 bytes for them
165:             */
166:            int mjiAttrs = MJI_NONE;
167:
168:            /**
169:             * this is a lazy evaluated mangled name consisting of the name and
170:             * arg type signature
171:             */
172:            private String uniqueName;
173:
174:            /**
175:             * Creates a new method info.
176:             */
177:            protected MethodInfo(Method m, ClassInfo c) {
178:                name = m.getName();
179:                signature = m.getSignature();
180:                ci = c;
181:
182:                code = loadCode(m);
183:                exceptions = loadExceptions(m);
184:                lineNumbers = loadLineNumbers(m);
185:                maxLocals = getMaxLocals(m);
186:                maxStack = getMaxStack(m);
187:                localVariableNames = loadLocalVariableNames(m);
188:                localVariableTypes = loadLocalVariableTypes(m);
189:                isStatic = m.isStatic();
190:                isSynchronized = m.isSynchronized();
191:                isNative = m.isNative();
192:
193:                // since that's used to store the method in the ClassInfo, and to
194:                // identify it in tne InvokeInstruction, we can set it here
195:                uniqueName = getUniqueName(name, signature);
196:            }
197:
198:            void setAtomic(boolean isAtomic) {
199:                this .isAtomic = isAtomic;
200:            }
201:
202:            public boolean isAtomic() {
203:                return isAtomic;
204:            }
205:
206:            void setSchedulingRelevance(int sr) {
207:                schedulingRelevance = sr;
208:            }
209:
210:            public Object clone() {
211:                try {
212:                    return super .clone();
213:                } catch (CloneNotSupportedException cnx) {
214:                    return null;
215:                }
216:            }
217:
218:            /**
219:             * NOTE - this only works in conjunction with a special StackFrame
220:             */
221:            MethodInfo createNativeCallStub() {
222:                MethodInfo mi = (MethodInfo) clone();
223:                String cname = ci.getName();
224:                InvokeInstruction insn;
225:
226:                if (isStatic) {
227:                    insn = new INVOKESTATIC(mi, cname, name, signature, 0, 0);
228:                } else if (name.equals("<init>")) {
229:                    insn = new INVOKESPECIAL(mi, cname, name, signature, 0, 0);
230:                } else {
231:                    insn = new INVOKEVIRTUAL(mi, cname, name, signature, 0, 0);
232:                }
233:
234:                mi.code = new Instruction[2];
235:                mi.code[0] = insn;
236:                mi.code[1] = new RETURN(mi, 1, 4);
237:
238:                // otherwise ThreadInfo.executeAtomicLinesStep chokes up
239:                mi.lineNumbers = null;
240:                mi.exceptions = null;
241:
242:                return mi;
243:            }
244:
245:            /**
246:             * return the minimal name that has to be unique for overloading
247:             * (name + argument part of signature)
248:             * used as a lookup key
249:             */
250:            public static String getUniqueName(String mname, String signature) {
251:                return (mname + signature.substring(0,
252:                        signature.indexOf(')') + 1));
253:            }
254:
255:            public static MethodInfo newInstance(Method m, ClassInfo c) {
256:                return (new MethodInfo(m, c));
257:            }
258:
259:            public static MethodInfo[] newInstanceArray(int length) {
260:                return (new MethodInfo[length]);
261:            }
262:
263:            public byte[] getArgumentTypes() {
264:                if (argTypes == null) {
265:                    argTypes = Types.getArgumentTypes(signature);
266:                }
267:
268:                return argTypes;
269:            }
270:
271:            public int getArgumentsSize() {
272:                if (argSize < 0) {
273:                    argSize = Types.getArgumentsSize(signature);
274:
275:                    if (!isStatic) {
276:                        argSize++;
277:                    }
278:                }
279:
280:                return argSize;
281:            }
282:
283:            /**
284:             * Returns the class the method belongs to.
285:             */
286:            public ClassInfo getClassInfo() {
287:                return ci;
288:            }
289:
290:            /**
291:             * Return the complete name of the method, including the class name.
292:             */
293:            public String getCompleteName() {
294:                return ci.getName() + "." + name + signature;
295:            }
296:
297:            public boolean isDeterministic(ThreadInfo ti) {
298:                if ((mjiAttrs & MJI_COND_DETERMINISTIC) != 0) {
299:                    return ci.isMethodCondDeterministic(ti, this );
300:                } else {
301:                    // really just makes sense if this is a MJI method
302:                    // but we will factor this into a subclass later-on anyway
303:                    return ((mjiAttrs & MJI_NONDETERMINISTIC) == 0);
304:                }
305:            }
306:
307:            public boolean isExecutable(ThreadInfo ti) {
308:                boolean canEnter = false;
309:
310:                if ((mjiAttrs & MJI_COND_EXECUTABLE) != 0) {
311:                    canEnter = ci.isMethodCondExecutable(ti, this );
312:                } else {
313:                    canEnter = canEnter(ti);
314:                }
315:
316:                return canEnter;
317:            }
318:
319:            /**
320:             * do we honor scheduling relevant insns in our body, or do we
321:             * (hopefully deliberately) ignore them
322:             */
323:            public boolean isBodySchedulingRelevant(ThreadInfo ti,
324:                    ElementInfo ei) {
325:                return (schedulingRelevance != SR_NEVERBODY);
326:            }
327:
328:            /**
329:             * is invocation of this method scheduling relevant
330:             */
331:            public boolean isSchedulingRelevant(ThreadInfo ti, ElementInfo ei) {
332:                switch (schedulingRelevance) {
333:                case SR_ALWAYS:
334:                    return true;
335:                case SR_RUNNABLES:
336:                    return ti.hasOtherRunnables();
337:                case SR_SYNC:
338:                    if (ei.getLockCount() == 0) {
339:                        return ti.hasOtherRunnables();
340:                    }
341:                }
342:
343:                return false;
344:            }
345:
346:            public boolean isCtor() {
347:                return (name.equals("<init>"));
348:            }
349:
350:            public boolean isInternalMethod() {
351:                // <2do> pcm - should turn this into an attribute for efficiency reasons
352:                return (name.equals("<clinit>") || uniqueName
353:                        .equals("finalize()"));
354:            }
355:
356:            public boolean isThreadEntry(ThreadInfo ti) {
357:                return (uniqueName.equals("run()") && (ti.countStackFrames() == 1));
358:            }
359:
360:            /**
361:             * Returns the full name of the method, name and signature.
362:             */
363:            public String getFullName() {
364:                return name + signature;
365:            }
366:
367:            /**
368:             * Returns a specific instruction.
369:             */
370:            public Instruction getInstruction(int i) {
371:                if (code == null) {
372:                    return null;
373:                }
374:
375:                if ((i < 0) || (i >= code.length)) {
376:                    return null;
377:                }
378:
379:                return code[i];
380:            }
381:
382:            /**
383:             * Returns the instruction at a certain position.
384:             */
385:            public Instruction getInstructionAt(int position) {
386:                if (code == null) {
387:                    return null;
388:                }
389:
390:                for (int i = 0, l = code.length; i < l; i++) {
391:                    if ((code[i] != null)
392:                            && (code[i].getPosition() == position)) {
393:                        return code[i];
394:                    }
395:                }
396:
397:                throw new JPFException("instruction not found");
398:            }
399:
400:            /**
401:             * Returns the instructions of the method.
402:             */
403:            public Instruction[] getInstructions() {
404:                return code;
405:            }
406:
407:            /**
408:             * Returns the line number for a given position.
409:             */
410:            public int getLineNumber(Instruction pc) {
411:                if (lineNumbers == null) {
412:                    return pc.getPosition();
413:                }
414:
415:                return lineNumbers[pc.getOffset()];
416:            }
417:
418:            /**
419:             * Returns a table to translate positions into line numbers.
420:             */
421:            public int[] getLineNumbers() {
422:                return lineNumbers;
423:            }
424:
425:            public boolean isMJI() {
426:                return ((mjiAttrs & MJI_NATIVE) != 0);
427:            }
428:
429:            public int getMaxLocals() {
430:                return maxLocals;
431:            }
432:
433:            public static int getMaxLocals(Method m) {
434:                Code c = m.getCode();
435:
436:                if (c == null) {
437:                    return 0;
438:                }
439:
440:                return c.getMaxLocals();
441:            }
442:
443:            public int getMaxStack() {
444:                return maxStack;
445:            }
446:
447:            public static int getMaxStack(Method m) {
448:                Code c = m.getCode();
449:
450:                if (c == null) {
451:                    return 0;
452:                }
453:
454:                return c.getMaxStack();
455:            }
456:
457:            public ExceptionHandler[] getExceptions() {
458:                return exceptions;
459:            }
460:
461:            public String[] getLocalVariableNames() {
462:                return localVariableNames;
463:            }
464:
465:            public String[] getLocalVariableTypes() {
466:                return localVariableTypes;
467:            }
468:
469:            /**
470:             * Returns the name of the method.
471:             */
472:            public String getName() {
473:                return name;
474:            }
475:
476:            /**
477:             * Returns true if the method is native
478:             */
479:            public boolean isNative() {
480:                return isNative;
481:            }
482:
483:            public int getNumberOfArguments() {
484:                if (nArgs < 0) {
485:                    nArgs = Types.getNumberOfArguments(signature);
486:                }
487:
488:                return nArgs;
489:            }
490:
491:            /**
492:             * Returns the size of the arguments.
493:             * This returns the number of parameters passed on the stack, incl. 'this'
494:             */
495:            public int getNumberOfStackArguments() {
496:                int n = getNumberOfArguments();
497:
498:                return isStatic ? n : n + 1;
499:            }
500:
501:            /**
502:             * do we return Object references?
503:             */
504:            public boolean isReferenceReturnType() {
505:                int r = getReturnType();
506:
507:                return ((r == Types.T_REFERENCE) || (r == Types.T_ARRAY));
508:            }
509:
510:            public byte getReturnType() {
511:                if (returnType < 0) {
512:                    returnType = Types.getReturnType(signature);
513:                }
514:
515:                return returnType;
516:            }
517:
518:            /**
519:             * Returns the signature of the method.
520:             */
521:            public String getSignature() {
522:                return signature;
523:            }
524:
525:            /**
526:             * Returns true if the field is static.
527:             */
528:            public boolean isStatic() {
529:                return isStatic;
530:            }
531:
532:            /**
533:             * Returns true if the field is synchronized.
534:             */
535:            public boolean isSynchronized() {
536:                return isSynchronized;
537:            }
538:
539:            public String getUniqueName() {
540:                return uniqueName;
541:            }
542:
543:            public boolean canEnter(ThreadInfo th) {
544:                if (isSynchronized) {
545:                    ElementInfo ei = getBlockedObject(th, true);
546:
547:                    // <?> pcm - the other way round would be intuitive
548:                    return ei.canLock(th);
549:                }
550:
551:                return true;
552:            }
553:
554:            public ElementInfo getBlockedObject(ThreadInfo th,
555:                    boolean isBeforeCall) {
556:                int objref;
557:                ElementInfo ei = null;
558:
559:                if (isSynchronized) {
560:                    if (isStatic) {
561:                        objref = ci.getClassObjectRef();
562:                    } else {
563:                        // NOTE 'inMethod' doesn't work for natives, because th.getThis()
564:                        // pulls 'this' from the stack frame, which we don't have (and don't need)
565:                        // for natives
566:                        objref = isBeforeCall ? th.getCalleeThis(this ) : th
567:                                .getThis();
568:                    }
569:
570:                    DynamicArea da = JVM.getVM().getDynamicArea();
571:                    ei = da.get(objref);
572:
573:                    if (ei == null) {
574:                        // ARGHH, broken this or class
575:                        throw new JPFException(
576:                                "inconsistent stack, no object or class ref: "
577:                                        + getCompleteName() + " (" + objref
578:                                        + ")");
579:                    }
580:                }
581:
582:                return ei;
583:            }
584:
585:            public void enter(ThreadInfo th) {
586:                if (isSynchronized) {
587:                    ElementInfo ei = getBlockedObject(th, false);
588:                    ei.lock(th);
589:                }
590:            }
591:
592:            public void leave(ThreadInfo th) {
593:                if (isSynchronized) {
594:                    ElementInfo ei = getBlockedObject(th, false);
595:                    ei.unlock(th);
596:                }
597:            }
598:
599:            /**
600:             * execute this method, which might be either bytecode or native.
601:             */
602:            public Instruction execute(ThreadInfo ti, boolean isDirectCall) {
603:                if (((mjiAttrs & MJI_NATIVE) != 0) || isNative) {
604:                    // if we have a native method which is not MJI_NATIVE, we are in
605:                    // trouble (ends up in UnsatisfiedLinkErrors)
606:                    // the opposite (MJI_NATIVE but not native) is questionable, but legal
607:                    // (you better know what code you cut off)
608:                    return ci.executeNativeMethod(ti, this );
609:                } else {
610:                    ti.pushFrame(new StackFrame(this , isDirectCall, ti.top()));
611:                    enter(ti);
612:
613:                    return ti.getPC();
614:                }
615:            }
616:
617:            /**
618:             * Loads the code of the method.
619:             */
620:            protected Instruction[] loadCode(Method m) {
621:                Code c = m.getCode();
622:
623:                if (c == null) {
624:                    return null;
625:                }
626:
627:                InstructionList il = new InstructionList(c.getCode());
628:
629:                InstructionHandle[] hs = il.getInstructionHandles();
630:                int length = hs.length;
631:
632:                Instruction[] is = new Instruction[length];
633:
634:                for (int i = 0; i < length; i++) {
635:                    is[i] = Instruction.create(hs[i], i, this , m
636:                            .getConstantPool());
637:
638:                    if (c.getLineNumberTable() != null) {
639:                        // annoying bug when BCEL don't seem to find linenumber - pos match
640:                        // also sometimes linenumber tables are not available
641:                        is[i].setContext(ci.getName(), name, c
642:                                .getLineNumberTable().getSourceLine(
643:                                        is[i].getPosition()), is[i]
644:                                .getPosition());
645:                    }
646:                }
647:
648:                return is;
649:            }
650:
651:            /**
652:             * Returns the exceptions of the method.
653:             */
654:            protected ExceptionHandler[] loadExceptions(Method m) {
655:                Code c = m.getCode();
656:
657:                if (c == null) {
658:                    return null;
659:                }
660:
661:                CodeException[] ce = c.getExceptionTable();
662:
663:                if (ce.length == 0) {
664:                    return null;
665:                }
666:
667:                int length = ce.length;
668:                ExceptionHandler[] eh = new ExceptionHandler[length];
669:
670:                ConstantPool cp = m.getConstantPool();
671:
672:                for (int i = 0; i < length; i++) {
673:                    int ct = ce[i].getCatchType();
674:                    eh[i] = new ExceptionHandler(((ct == 0) ? null : cp
675:                            .getConstantString(ct, Constants.CONSTANT_Class)
676:                            .replace('/', '.')), ce[i].getStartPC(), ce[i]
677:                            .getEndPC(), ce[i].getHandlerPC());
678:                }
679:
680:                return eh;
681:            }
682:
683:            /**
684:             * Loads the line numbers for the method.
685:             */
686:            protected int[] loadLineNumbers(Method m) {
687:                Code c = m.getCode();
688:
689:                if (c == null) {
690:                    return null;
691:                }
692:
693:                LineNumberTable lnt = c.getLineNumberTable();
694:
695:                int length = code.length;
696:                int[] ln = new int[length];
697:
698:                if (lnt == null) {
699:                    // no line information
700:                    return null;
701:                } else {
702:                    for (int i = 0; i < length; i++) {
703:                        try { //annoying bug when BCEL don't seem to find linenumber - pos match
704:                            ln[i] = lnt.getSourceLine(code[i].getPosition());
705:                        } catch (RuntimeException e) {
706:                            System.out.print("^");
707:                        }
708:                    }
709:                }
710:
711:                return ln;
712:            }
713:
714:            /**
715:             * Loads the names of the local variables.
716:             *
717:             * NOTE: BCEL only gives us a list of all *named* locals, which might not
718:             * include all local vars (temporaries, like StringBuffer). Note that we have
719:             * to fill this with "?" inorder to make the returned array correspond with
720:             * slot numbers
721:             */
722:            protected String[] loadLocalVariableNames(Method m) {
723:                Code c = m.getCode();
724:
725:                if (c == null) {
726:                    return null;
727:                }
728:
729:                LocalVariableTable lvt = c.getLocalVariableTable();
730:
731:                if (lvt == null) {
732:                    if (!warnedLocalInfo && !ci.isSystemClass()) {
733:                        Debug.println(Debug.WARNING);
734:                        Debug.println(Debug.WARNING,
735:                                "No local variable information available");
736:                        Debug
737:                                .println(Debug.WARNING, "for "
738:                                        + getCompleteName());
739:                        Debug
740:                                .println(Debug.WARNING,
741:                                        "Recompile with -g to include this information");
742:                        Debug.println(Debug.WARNING);
743:                        warnedLocalInfo = true;
744:                    }
745:
746:                    return null;
747:                }
748:
749:                LocalVariable[] lv = lvt.getLocalVariableTable();
750:                int length = lv.length;
751:                String[] v = new String[c.getMaxLocals()];
752:
753:                for (int i = 0; i < length; i++) {
754:                    v[lv[i].getIndex()] = lv[i].getName();
755:                }
756:
757:                for (int i = 0; i < v.length; i++) {
758:                    if (v[i] == null) {
759:                        v[i] = "?";
760:                    }
761:                }
762:
763:                return v;
764:            }
765:
766:            /**
767:             * Loads the types of the local variables.
768:             * see loadLocalVariableNames for the problem with temporaries and
769:             * why we can't copy the types 1:1
770:             */
771:            protected String[] loadLocalVariableTypes(Method m) {
772:                Code c = m.getCode();
773:
774:                if (c == null) {
775:                    return null;
776:                }
777:
778:                LocalVariableTable lvt = c.getLocalVariableTable();
779:
780:                if (lvt == null) {
781:                    if (!warnedLocalInfo && !ci.isSystemClass()) {
782:                        Debug.println(Debug.WARNING,
783:                                "No local variable information available");
784:                        Debug
785:                                .println(Debug.WARNING, "for "
786:                                        + getCompleteName());
787:                        Debug
788:                                .println(Debug.WARNING,
789:                                        "Recompile with -g to include this information");
790:                        Debug.println(Debug.WARNING);
791:                        warnedLocalInfo = true;
792:                    }
793:
794:                    return null;
795:                }
796:
797:                LocalVariable[] lv = lvt.getLocalVariableTable();
798:                int length = lv.length;
799:                String[] v = new String[c.getMaxLocals()];
800:
801:                for (int i = 0; i < length; i++) {
802:                    v[lv[i].getIndex()] = lv[i].getSignature();
803:                }
804:
805:                for (int i = 0; i < v.length; i++) {
806:                    if (v[i] == null) {
807:                        v[i] = "?";
808:                    }
809:                }
810:
811:                return v;
812:            }
813:
814:            void setCondDeterministic(boolean isCondDeterministic) {
815:                if (isCondDeterministic) {
816:                    mjiAttrs |= MJI_COND_DETERMINISTIC;
817:                } else {
818:                    mjiAttrs &= ~MJI_COND_DETERMINISTIC;
819:                }
820:            }
821:
822:            void setCondExecutable(boolean isCondExecutable) {
823:                if (isCondExecutable) {
824:                    mjiAttrs |= MJI_COND_EXECUTABLE;
825:                } else {
826:                    mjiAttrs &= ~MJI_COND_EXECUTABLE;
827:                }
828:            }
829:
830:            void setDeterministic(boolean isDeterministic) {
831:                if (isDeterministic) {
832:                    mjiAttrs &= ~MJI_NONDETERMINISTIC;
833:                } else {
834:                    mjiAttrs |= MJI_NONDETERMINISTIC;
835:                }
836:            }
837:
838:            void setMJI(boolean isMJI) {
839:                if (isMJI) {
840:                    mjiAttrs |= MJI_NATIVE;
841:                } else {
842:                    mjiAttrs &= ~MJI_NATIVE;
843:                }
844:            }
845:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.