Source Code Cross Referenced for AdaptorGen.java in  » Scripting » jacl » tcl » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


0001:        /*
0002:         * AdaptorGen.java --
0003:         *
0004:         *	Generates adaptor class for the java::bind command to handle
0005:         *	JavaBean events.
0006:         *
0007:         * Copyright (c) 1997 Sun Microsystems, Inc.
0008:         *
0009:         * See the file "license.terms" for information on usage and
0010:         * redistribution of this file, and for a DISCLAIMER OF ALL
0011:         * WARRANTIES.
0012:         *
0013:         * RCS: @(#) $Id: AdaptorGen.java,v 1.3 2000/01/25 03:42:26 mo Exp $
0014:         */
0015:
0016:        package tcl.lang;
0017:
0018:        import java.util.*;
0019:        import java.lang.reflect.*;
0020:        import java.beans.*;
0021:        import java.io.*;
0022:
0023:        /**
0024:         * AdaptorGen is the event adaptor class generator. It can generate an
0025:         * event adaptor class that implements any given JavaBean event
0026:         * interface. The generated class is used to provide a callback
0027:         * mechanism for JavaBeans to invoke Tcl scripts.
0028:         *
0029:         * The program in src/test/AdaptorGenTest.java can be used to test the
0030:         * operation of the AdaptorGen class -- it saves the data generated by
0031:         * the AdaptorGen class into a .class file, which can then be examined
0032:         * using tools such as javap.
0033:         */
0034:
0035:        class AdaptorGen {
0036:
0037:            // Constant pool types.
0038:
0039:            private static final int CONSTANT_Class = 7;
0040:            private static final int CONSTANT_FieldRef = 9;
0041:            private static final int CONSTANT_MethodRef = 10;
0042:            private static final int CONSTANT_InterfaceMethodRef = 11;
0043:            private static final int CONSTANT_String = 8;
0044:            private static final int CONSTANT_Integer = 3;
0045:            private static final int CONSTANT_Float = 4;
0046:            private static final int CONSTANT_Long = 5;
0047:            private static final int CONSTANT_Double = 6;
0048:            private static final int CONSTANT_NameAndType = 12;
0049:            private static final int CONSTANT_Utf8 = 1;
0050:
0051:            // Java op-codes used by the adaptor class.
0052:
0053:            private static final int ALOAD = 0x19;
0054:            private static final int ALOAD_0 = 0x2a;
0055:            private static final int ALOAD_1 = 0x2b;
0056:            private static final int ICONST_0 = 0x3;
0057:            private static final int ICONST_1 = 0x4;
0058:            private static final int ANEWARRAY = 0xbd;
0059:            private static final int DUP = 0x59;
0060:            private static final int AASTORE = 0x53;
0061:            private static final int RETURN = 0xb1;
0062:            private static final int ARETURN = 0xb0;
0063:            private static final int DRETURN = 0xaf;
0064:            private static final int FRETURN = 0xae;
0065:            private static final int IRETURN = 0xac;
0066:            private static final int LRETURN = 0xad;
0067:            private static final int SIPUSH = 0x11;
0068:            private static final int ASTORE = 0x3a;
0069:            private static final int NEW = 0xbb;
0070:            private static final int ILOAD = 0x15;
0071:            private static final int LLOAD = 0x16;
0072:            private static final int FLOAD = 0x17;
0073:            private static final int DLOAD = 0x18;
0074:            private static final int INVOKESP = 0xb7;
0075:            private static final int INVOKEVT = 0xb6;
0076:            private static final int WIDE = 0xc4;
0077:            private static final int LDC_W = 0x13;
0078:            private static final int INSTNCOF = 0xc1;
0079:            private static final int CHKCAST = 0xc0;
0080:            private static final int IFEQ = 0x99;
0081:            private static final int ATHROW = 0xbf;
0082:            private static final int GOTO_W = 0xc8;
0083:
0084:            // Access modifiers.
0085:
0086:            private static final int ACC_PUBLIC = 0x0001;
0087:            private static final int ACC_SUPER = 0x0020;
0088:
0089:            // These are internal variable shared among the methods of this
0090:            // class. We declare them as member variables so that we don't need to
0091:            // pass them explicitly to all methods.
0092:
0093:            private DataOutputStream ostream;
0094:            private Class listenerCls;
0095:            private Method methods[];
0096:            private String clsName;
0097:            private Class super Cls;
0098:
0099:            // The number of items that have been added into the constant pool so
0100:            // far. It starts at 1 because there is always an implicit item #0
0101:            // in the constant pool.
0102:
0103:            int cpSize;
0104:
0105:            // This Vector is used to hold temporarily the constant pool elements
0106:            // when we are counting the number of elements in the constant pool.
0107:
0108:            Vector constPool;
0109:
0110:            // Stores all the UTF string constants that are currently in the
0111:            // constant pool. We use this information to avoid having duplicate
0112:            // copies of the same string in the constant pool.
0113:
0114:            Hashtable utf8Tab;
0115:
0116:            // The hashtable stores the Class objects of all the Object types
0117:            // referenced by the adaptor class, including:
0118:            //
0119:            //	+ Object types passed in as parameters to the methods of
0120:            //	  the adaptor class.
0121:            //	+ Object types returned by the methods of the adaptor class.
0122:            //	+ Wrapper Object types used to pass event parameters
0123:            //	  to _processEvent().
0124:            //	+ Exception types thrown by the methods of the adaptor
0125:            //	  class.
0126:
0127:            Hashtable allClasses;
0128:
0129:            // This hashtable contains all the Class objects of the primitive
0130:            // types used in the adaptor class.
0131:
0132:            Hashtable primClasses;
0133:
0134:            // This hashtable contains all the primitive types returned by the
0135:            // methods of the interface. It will also contain Object.class if
0136:            // there is a method that returns an object (of any class).
0137:
0138:            Hashtable returnTypes;
0139:
0140:            // This hashtable contains the constant pool IDs for the _return_<type>
0141:            // methods.
0142:
0143:            Hashtable returnMethodRef;
0144:
0145:            // This hashtable stores the constant pool IDs for the constructors of
0146:            // the wrapper classes that are used to pass parameters of primitive
0147:            // types to the _processEvent() method.
0148:
0149:            Hashtable wrapperConsRef;
0150:
0151:            // This hashtable contains the constant pool IDs for all the classes
0152:            // referenced by the adaptor class.
0153:
0154:            Hashtable clsRef;
0155:
0156:            // This hashtable contains the constant pool IDs for all the strings
0157:            // referenced by the adaptor class.
0158:
0159:            Hashtable stringRef;
0160:
0161:            // The constant pool ID of the adaptor class.
0162:
0163:            short cp_this _class;
0164:
0165:            // The constant pool ID of the super class of the adaptor class
0166:            // (tcl.lang.EventAdaptor).
0167:
0168:            short cp_super _class;
0169:
0170:            // The constant pool ID of the event interface that the adaptor class
0171:            // implements.
0172:
0173:            short cp_listener_interface;
0174:
0175:            // The constant pool ID of the "Code" string, which is used to
0176:            // identify a section of executable code in the class file.
0177:
0178:            short cp_code;
0179:
0180:            // The constant pool ID of the constructor of the super class.
0181:
0182:            short cp_super _cons;
0183:
0184:            // The constant pool ID of the _processEvent() method in the super
0185:            // class.
0186:
0187:            short cp_processEvent;
0188:
0189:            // The constant pool ID of the _wrongException() method in the super
0190:            // class.
0191:
0192:            short cp_wrongException;
0193:
0194:            // Stores information about each method in the adaptor class.
0195:            // cp_methodDesc[i] contains info about method[i].
0196:
0197:            MethodDesc cp_methodDesc[];
0198:
0199:            // Store information about the constructor of the adaptor class.
0200:
0201:            MethodDesc cp_consDesc;
0202:
0203:            /*
0204:             *----------------------------------------------------------------------
0205:             *
0206:             * generate --
0207:             *
0208:             *	Generate the byte code of an adaptor class that implements the
0209:             *	event interface of the given event.
0210:             *
0211:             * Results:
0212:             *	A byte array that contains the byte code of the adaptor class.
0213:             *
0214:             * Side effects:
0215:             *	None.
0216:             *
0217:             *----------------------------------------------------------------------
0218:             */
0219:
0220:            byte[] generate(EventSetDescriptor desc, Class super Class,
0221:                    String className) {
0222:                // Copy these arguments into member variables so that they don't need
0223:                // to be passed into the internal methods called by generateByteCode().
0224:
0225:                super Cls = super Class;
0226:                clsName = className;
0227:                listenerCls = desc.getListenerType();
0228:                methods = listenerCls.getMethods();
0229:
0230:                // Initialize other member variables used to generate the byte code.
0231:                // These variables must be re-initialize each time a new class is to
0232:                // be generated.
0233:
0234:                allClasses = new Hashtable();
0235:                primClasses = new Hashtable();
0236:                returnTypes = new Hashtable();
0237:
0238:                returnMethodRef = new Hashtable();
0239:                wrapperConsRef = new Hashtable();
0240:                clsRef = new Hashtable();
0241:                stringRef = new Hashtable();
0242:                utf8Tab = new Hashtable();
0243:                cp_methodDesc = new MethodDesc[methods.length];
0244:                analyzeListener();
0245:                cpSize = 1;
0246:
0247:                // Generate the data of the adaptor class that implements the
0248:                // event interface given by desc.
0249:
0250:                try {
0251:                    // Prepare the output streams.
0252:
0253:                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
0254:                    DataOutputStream dos = new DataOutputStream(baos);
0255:                    ostream = dos;
0256:
0257:                    // Generate the data.
0258:
0259:                    generateByteCode();
0260:
0261:                    return baos.toByteArray();
0262:
0263:                } catch (IOException e) {
0264:                    throw new TclRuntimeError("Unexcepted IOException " + e);
0265:                }
0266:            }
0267:
0268:            /*
0269:             *----------------------------------------------------------------------
0270:             *
0271:             * analizeListener --
0272:             *
0273:             *	Find out information about the listener class:
0274:             *
0275:             *	  - How many method are there.
0276:             *	  - What exceptions (if any) are thrown by the methods.
0277:             *	  - The argument types of the methods
0278:             *	  - The return types of the methods.
0279:             *	
0280:             *	From this information, we can determine what to put in the constant
0281:             *	pools:
0282:             *
0283:             *	  - All the classes referred to by the arguments, checked exception
0284:             *	    and return types.
0285:             *	  - All the primitive wrapper classes needed to pass primitive
0286:             *	    arguments to the super.processEvent()
0287:             *	  - All the super.return<type> methods needed by the return types
0288:             *	    of the methods.
0289:             *
0290:             *	One reason for obtaining the information is to reduce the size
0291:             *	of the constant pool. E.g., if we know that none of the methods
0292:             *	returns int values, then we don't need to put the method
0293:             *	_return_int() into the constant pool.
0294:             *
0295:             * Results:
0296:             *	None.
0297:             *
0298:             * Side effects:
0299:             *	Infomation about the listener class are recorded in various member
0300:             *	variables.
0301:             *
0302:             *----------------------------------------------------------------------
0303:             */
0304:
0305:            private void analyzeListener() {
0306:                int i, j;
0307:                boolean paramsDefined = false;
0308:
0309:                for (i = 0; i < methods.length; i++) {
0310:                    Class params[] = methods[i].getParameterTypes();
0311:
0312:                    // Record all classes (including wrapper classes) that will
0313:                    // be used to pass parameters to _processEvent().
0314:
0315:                    for (j = 0; j < params.length; j++) {
0316:                        if (params[j].isPrimitive()) {
0317:                            if (params[j] == Void.TYPE) {
0318:                                // Looks likes the JVM has loaded a bad interface class:
0319:                                // one of the parameter of an interface is of type void.
0320:
0321:                                throw new ClassFormatError(
0322:                                        "Parameter type cannot be void");
0323:                            }
0324:                            Class wrapper = getWrapperClass(params[j]);
0325:                            allClasses.put(wrapper, wrapper);
0326:                            primClasses.put(params[j], params[j]);
0327:                        } else {
0328:                            allClasses.put(params[j], params[j]);
0329:                        }
0330:                        paramsDefined = true;
0331:                    }
0332:
0333:                    // Record all exceptions thrown by the methods.
0334:
0335:                    Class exceptions[] = methods[i].getExceptionTypes();
0336:                    for (j = 0; j < exceptions.length; j++) {
0337:                        allClasses.put(exceptions[j], exceptions[j]);
0338:                    }
0339:
0340:                    // Record information about the return types of the methods.
0341:
0342:                    Class retType = methods[i].getReturnType();
0343:                    if (retType != Void.TYPE) {
0344:                        if (!retType.isPrimitive()) {
0345:                            allClasses.put(retType, retType);
0346:                        }
0347:                        returnTypes.put(retType, retType);
0348:                    }
0349:                }
0350:
0351:                if (paramsDefined) {
0352:                    allClasses.put(Object.class, Object.class);
0353:                }
0354:
0355:                allClasses.put(Throwable.class, Throwable.class);
0356:            }
0357:
0358:            /*
0359:             *----------------------------------------------------------------------
0360:             *
0361:             * generateByteCode --
0362:             *
0363:             *	Writes out the byte code into the ostream.
0364:             *
0365:             * Results:
0366:             *
0367:             *	None.
0368:             *
0369:             * Side effects:
0370:             *	Byte code is written into the ostream.
0371:             *
0372:             *----------------------------------------------------------------------
0373:             */
0374:
0375:            private void generateByteCode() throws IOException // This exception may never happen. We
0376:            // declare it just to avoid putting
0377:            // catch statements everywhere.
0378:            {
0379:                // u4 magic.
0380:                // u2 minor_version
0381:                // u2 major_version
0382:
0383:                ostream.writeInt(0xCAFEBABE);
0384:                ostream.writeShort(3);
0385:                ostream.writeShort(45);
0386:
0387:                // u2 constant_pool_count
0388:                // cp_info constant_pool[constant_pool_count-1]
0389:
0390:                generateConstantPool();
0391:
0392:                // u2 access_flags
0393:                // u2 this_class
0394:                // u2 super_class
0395:
0396:                ostream.writeShort(ACC_SUPER | ACC_PUBLIC);
0397:                ostream.writeShort(cp_this _class);
0398:                ostream.writeShort(cp_super _class);
0399:
0400:                // u2 interfaces_count
0401:                // u2 interfaces[interfaces_count]
0402:
0403:                ostream.writeShort(1);
0404:                ostream.writeShort(cp_listener_interface);
0405:
0406:                // u2 fields_count
0407:                // u2 field_info fields[fields_count]
0408:
0409:                ostream.writeShort(0);
0410:
0411:                // u2 methods_count
0412:                // u2 method_info methods[methods_count]
0413:
0414:                ostream.writeShort(1 + methods.length);
0415:                generateConstructor();
0416:
0417:                for (int i = 0; i < methods.length; i++) {
0418:                    generateMethod(i);
0419:                }
0420:
0421:                // u2 attributes_count
0422:                // u2 attribute_info attributes[attributes_count]
0423:
0424:                ostream.writeShort(0);
0425:            }
0426:
0427:            /*
0428:             *----------------------------------------------------------------------
0429:             *
0430:             * generateConstantPool --
0431:             *
0432:             *	Generate the constant pool.
0433:             *
0434:             * Results:
0435:             *	None.
0436:             *
0437:             * Side effects:
0438:             *	The constant pool elements are written into the byte array stream.
0439:             *
0440:             *----------------------------------------------------------------------
0441:             */
0442:
0443:            private void generateConstantPool() throws IOException // This exception may never happen because
0444:            // we are only writing to byte array
0445:            // streams. We declare it just to
0446:            // avoid putting catch statements
0447:            // everywhere.
0448:            {
0449:                // We do this in three stages because inside the byte code, the
0450:                // constant_pool_count appears in front of the constant pool
0451:                // elements.
0452:                //
0453:                //	(1) Generate the constant pool elements and store them into a 
0454:                //	    Vector. When we are done we know the total number of
0455:                //	    constants we have.
0456:                //
0457:                //	(2) Find out how many elements we have written, and write
0458:                //      constant_pool_count into the byte array stream.
0459:                //
0460:                //	(3) Write the constant pool elements into the byte array
0461:                //	    stream.
0462:                //
0463:
0464:                constPool = new Vector();
0465:
0466:                // Names of this class, its super class and the interface that
0467:                // this class implements.
0468:
0469:                cp_this _class = cp_putClass(clsName);
0470:                cp_super _class = cp_putClass(super Cls.getName());
0471:
0472:                cp_listener_interface = cp_putClass(listenerCls.getName());
0473:
0474:                // The UTF8 string "Code" is used to generate the body of methods.
0475:
0476:                cp_code = cp_putUtf8("Code");
0477:
0478:                // All the methods that the generated class calls.
0479:
0480:                cp_super _cons = cp_putMethodRef(cp_super _class, "<init>", "()V");
0481:                cp_processEvent = cp_putMethodRef(cp_super _class,
0482:                        "_processEvent",
0483:                        "([Ljava/lang/Object;Ljava/lang/String;)V");
0484:                cp_wrongException = cp_putMethodRef(cp_super _class,
0485:                        "_wrongException", "()V");
0486:
0487:                for (Enumeration e = returnTypes.keys(); e.hasMoreElements();) {
0488:                    Class retType = (Class) e.nextElement();
0489:                    short ref;
0490:
0491:                    if (retType.isPrimitive()) {
0492:                        ref = cp_putMethodRef(cp_super _class, "_return_"
0493:                                + retType.getName(), "()"
0494:                                + getTypeDesc(retType));
0495:                    } else {
0496:                        cp_putString(retType.getName());
0497:                        ref = cp_putMethodRef(cp_super _class, "_return_Object",
0498:                                "(Ljava/lang/String;)" + getTypeDesc(retType));
0499:                    }
0500:
0501:                    hashPutShort(returnMethodRef, retType, ref);
0502:                }
0503:
0504:                // The constructor and methods that are defined in the generated
0505:                // class.
0506:
0507:                cp_consDesc = cp_putMethodDesc("<init>", "()V", false);
0508:
0509:                for (int i = 0; i < methods.length; i++) {
0510:                    cp_methodDesc[i] = cp_putMethodDesc(methods[i].getName(),
0511:                            getMethodDescriptor(methods[i]), true);
0512:                }
0513:
0514:                // All the classes referred to by the generated class.
0515:
0516:                for (Enumeration e = allClasses.keys(); e.hasMoreElements();) {
0517:                    Class type = (Class) e.nextElement();
0518:
0519:                    short ref = cp_putClass(type.getName());
0520:                    hashPutShort(clsRef, type, ref);
0521:                }
0522:
0523:                // If the methods in the generated class receives parameter of
0524:                // primitive types, they must be wrapped in wrapper classes such
0525:                // as java.lang.Integer before they are passed to
0526:                // super._processEvent().
0527:
0528:                for (Enumeration e = primClasses.keys(); e.hasMoreElements();) {
0529:                    // FIXME : javac compiler bug workaround
0530:                    //
0531:                    // This loop works around a compiler bug in JAVAC 1.1.4. For
0532:                    // For some reasons, if this loop is not here, AdaptorGen.class will
0533:                    // contain incorrect byte code and causes a NullPoniterException.
0534:                    // 
0535:                    // This compiler bug happens only in JAVAC. MS JVC apparently
0536:                    // works fine.
0537:
0538:                    e.nextElement();
0539:                }
0540:
0541:                for (Enumeration e = primClasses.keys(); e.hasMoreElements();) {
0542:                    Class primType = (Class) e.nextElement();
0543:                    short class_index = cp_getClass(getWrapperClass(primType));
0544:                    short ref = cp_putMethodRef(class_index, "<init>", "("
0545:                            + getTypeDesc(primType) + ")V");
0546:
0547:                    hashPutShort(wrapperConsRef, primType, ref);
0548:                }
0549:
0550:                // Now we know the count. Let's write into the byte array.
0551:
0552:                ostream.writeShort(constPool.size() + 1);
0553:                for (int i = 0; i < constPool.size(); i++) {
0554:                    Object obj = constPool.elementAt(i);
0555:
0556:                    if (obj instanceof  ConstUtf) {
0557:                        ConstUtf cutf = (ConstUtf) obj;
0558:
0559:                        ostream.writeByte(CONSTANT_Utf8);
0560:                        ostream.writeUTF(cutf.string);
0561:
0562:                    } else if (obj instanceof  ConstString) {
0563:                        ConstString cstr = (ConstString) obj;
0564:
0565:                        ostream.writeByte(CONSTANT_String);
0566:                        ostream.writeShort(cstr.string_index);
0567:
0568:                    } else if (obj instanceof  ConstClass) {
0569:                        ConstClass ccls = (ConstClass) obj;
0570:
0571:                        ostream.writeByte(CONSTANT_Class);
0572:                        ostream.writeShort(ccls.name_index);
0573:
0574:                    } else if (obj instanceof  ConstMethodRef) {
0575:                        ConstMethodRef cmref = (ConstMethodRef) obj;
0576:
0577:                        ostream.writeByte(CONSTANT_MethodRef);
0578:                        ostream.writeShort(cmref.class_index);
0579:                        ostream.writeShort(cmref.name_and_type_index);
0580:
0581:                    } else {
0582:                        ConstNameAndType cnat = (ConstNameAndType) obj;
0583:
0584:                        ostream.writeByte(CONSTANT_NameAndType);
0585:                        ostream.writeShort(cnat.name_index);
0586:                        ostream.writeShort(cnat.desc_index);
0587:                    }
0588:                }
0589:            }
0590:
0591:            /*
0592:             *----------------------------------------------------------------------
0593:             *
0594:             * generateConstructor --
0595:             *
0596:             *	Generates the constructor method -- it just chains to the
0597:             *	constructor of the super class. E.g.
0598:             *
0599:             *	    public Adaptor0() {
0600:             *     		super();
0601:             * 	    }
0602:             *
0603:             *	Note we need to generate such an "implicit constructor"
0604:             *	anyways. The JVM requires this. We can omit implicit
0605:             *	constructor in Java source code because JAVAC makes one for us
0606:             *	behind the scene.
0607:             *
0608:             * Results:
0609:             *	None.
0610:             *
0611:             * Side effects:
0612:             *	The byte code of the constructor is written into the ostream.
0613:             *
0614:             *----------------------------------------------------------------------
0615:             */
0616:
0617:            void generateConstructor() throws IOException // This exception may never happen. We
0618:            // declare it just to avoid putting
0619:            // catch statements everywhere.
0620:            {
0621:                ostream.writeShort(ACC_PUBLIC); // access
0622:                ostream.writeShort(cp_consDesc.name_index);
0623:                ostream.writeShort(cp_consDesc.descriptor_index);
0624:                ostream.writeShort(1); // attr count
0625:
0626:                ostream.writeShort(cp_code); // attr_name_index = "Code"
0627:                ostream.writeInt(17); // attr_length,excluding first 6 bytes
0628:                ostream.writeShort(2); // max_stacks
0629:                ostream.writeShort(1); // max_locals
0630:                ostream.writeInt(5); // code_length
0631:
0632:                ostream.writeByte(ALOAD_0); // aload_0
0633:
0634:                ostream.writeByte(INVOKESP); // invokespecial super.<init>()
0635:                ostream.writeShort(cp_super _cons);
0636:
0637:                ostream.writeByte(RETURN); // return
0638:
0639:                ostream.writeShort(0); // exception_table_length
0640:                ostream.writeShort(0); // attribute_count
0641:            }
0642:
0643:            /*
0644:             *----------------------------------------------------------------------
0645:             *
0646:             * generateMethod --
0647:             *
0648:             *	Generates an event handling method. This procedure is more
0649:             *	complex because the method can receive any parameters, throw
0650:             *	any exceptions and return any value. Here is a canonical form
0651:             *	of the kind of method generated:
0652:             *
0653:             *	    public int someEvent(int p0, double p1, byte p2, Object p3)
0654:             *	        throws Exception1, Exception2
0655:             *	    {
0656:             *		Object params[] = new Object[4];
0657:             *		params[0] = new Integer(p0);
0658:             *		params[1] = new Double(p1);
0659:             *		params[2] = new Byte(p2);
0660:             *		params[3] = p3;
0661:             *		
0662:             *		try {
0663:             *		    _processEvent(params, "someEvent");
0664:             *		} catch (Throwable exception) {
0665:             *		    if (exception instanceof Exception1) {
0666:             *		        throw (Exception1)exception;
0667:             *		    } else if (exception instanceof Exception2) {
0668:             *		        throw (Exception2)exception;
0669:             *		    } else {
0670:             *			_wrongException();
0671:             *		    }
0672:             *		}
0673:             *
0674:             *		return _return_int();
0675:             *	    }
0676:             *
0677:             *
0678:             *	If the return type is any Object type, the final statement
0679:             *	will be modified as in the following:
0680:             *
0681:             *	    public xyz.pkg.FooBar someEvent(...)
0682:             *	    {
0683:             *		....
0684:             *		return (FooBar)_return_Object("xyz.pkg.FooBar");
0685:             *	    }
0686:             *	
0687:             *	The actual work of converting interp.getResult() to the
0688:             *	appropriate return type is done in the _return_<type> methods
0689:             *	in the EventAdaptor class.
0690:             *
0691:             * Results:
0692:             *	None.
0693:             *
0694:             * Side effects:
0695:             *	The byte code of the method is written into the ostream.
0696:             *
0697:             *----------------------------------------------------------------------
0698:             */
0699:
0700:            void generateMethod(int methodIdx) // Generate the method  described by
0701:                    // methods[methodIdx].
0702:                    throws IOException {
0703:
0704:                int max_stacks;
0705:                int max_locals;
0706:                int paramVarIdx; // index of the "param" variable.
0707:                int exceptionVarIdx; // index of the "exception" variable.
0708:                int exStartPC, exEndPC; // Exception start and end PC.
0709:                int exHandlerPC = 0; // Exception handler PC.
0710:
0711:                // Calculate the max_stacks and max_locals variables for the
0712:                // method.
0713:
0714:                max_stacks = 6;
0715:
0716:                Class paramTypes[] = methods[methodIdx].getParameterTypes();
0717:                int numParams = paramTypes.length;
0718:
0719:                max_locals = 1; // "this" pointer
0720:                for (int i = 0; i < numParams; i++) {
0721:                    if ((paramTypes[i] == Double.TYPE)
0722:                            || (paramTypes[i] == Long.TYPE)) {
0723:                        max_locals += 2;
0724:                    } else {
0725:                        max_locals += 1;
0726:                    }
0727:                }
0728:
0729:                max_locals += 2; // param[], exception.
0730:                paramVarIdx = max_locals - 2;
0731:                exceptionVarIdx = max_locals - 1;
0732:
0733:                ostream.writeShort(ACC_PUBLIC); // access = "public"
0734:                ostream.writeShort(cp_methodDesc[methodIdx].name_index);
0735:                ostream.writeShort(cp_methodDesc[methodIdx].descriptor_index);
0736:                ostream.writeShort(1); // attr count
0737:
0738:                // Generate the body of the code.
0739:
0740:                ByteArrayOutputStream baos = new ByteArrayOutputStream();
0741:                DataOutputStream code = new DataOutputStream(baos);
0742:
0743:                // [1] Create an array for passing parameters to super.processEvent():
0744:                //
0745:                //     Object params[] = new Object[numParams];
0746:                //
0747:                // NOTE:
0748:                //
0749:                //   - In all the generated code, it is sufficient to represent
0750:                //	   a local variable using a short because a Java method may
0751:                //	   have no more than 65535 local variables (including paramaters).
0752:                //
0753:                //   - This means the side of the params array is no more than 65535,
0754:                //     so we can specify its size using sipush.
0755:
0756:                code.writeByte(SIPUSH); // sipush	#<numParams>
0757:                code.writeShort(numParams);
0758:
0759:                code.writeByte(ANEWARRAY); // anewarray	Object
0760:                code.writeShort(cp_getClass(Object.class));
0761:
0762:                writeLoadStore(code, ASTORE, // astore	param[]
0763:                        paramVarIdx);
0764:
0765:                // [2] Copy the parameters into an object array:
0766:                //
0767:                //	   params[0] = new Integer(p0);
0768:                //	   params[1] = new Double(p0);
0769:                //	   params[2] = (Object)p2;
0770:                //	   // .... etc
0771:
0772:                // We start at local variable index 1, which is the first parameter.
0773:                // (index 0 is the "this" pointer).
0774:
0775:                int paramIdx = 1;
0776:
0777:                for (int i = 0; i < numParams; i++) {
0778:                    writeLoadStore(code, ALOAD, // aload	param[]
0779:                            paramVarIdx);
0780:
0781:                    code.writeByte(SIPUSH); // sipush	#<i>	
0782:                    code.writeShort(i);
0783:
0784:                    if (paramTypes[i].isPrimitive()) {
0785:                        Class prim = paramTypes[i];
0786:                        Class wrapper = getWrapperClass(paramTypes[i]);
0787:                        int loadOpcode, numWords;
0788:
0789:                        if (prim == Double.TYPE) {
0790:                            loadOpcode = DLOAD;
0791:                            numWords = 2;
0792:                        } else if (prim == Float.TYPE) {
0793:                            loadOpcode = FLOAD;
0794:                            numWords = 1;
0795:                        } else if (prim == Long.TYPE) {
0796:                            loadOpcode = LLOAD;
0797:                            numWords = 2;
0798:                        } else {
0799:                            loadOpcode = ILOAD;
0800:                            numWords = 1;
0801:                        }
0802:
0803:                        code.writeByte(NEW); // new		<Wrapper>
0804:                        code.writeShort(cp_getClass(wrapper));
0805:
0806:                        code.writeByte(DUP); // dup
0807:
0808:                        writeLoadStore(code, // <?>load	p_<i>
0809:                                loadOpcode, paramIdx);
0810:
0811:                        code.writeByte(INVOKESP); // invokespecial <Wrapper>(<type>);
0812:                        code.writeShort(cp_getWrapperConstructor(prim));
0813:
0814:                        paramIdx += numWords;
0815:                    } else {
0816:                        writeLoadStore(code, ALOAD, // aload	p_<i>
0817:                                paramIdx);
0818:
0819:                        paramIdx += 1;
0820:                    }
0821:
0822:                    code.writeByte(AASTORE); // aastore
0823:                }
0824:
0825:                // [3] Call super.processEvent():
0826:                //
0827:                //     try {
0828:                //	   	super.processEvent(params, <nameOfMethod>);
0829:                //     }
0830:
0831:                exStartPC = code.size();
0832:
0833:                code.writeByte(ALOAD_0); // aload_0	this
0834:
0835:                writeLoadStore(code, ALOAD, // aload	param[]
0836:                        paramVarIdx);
0837:
0838:                code.writeByte(LDC_W); // ldc_w	<name_of_method>
0839:                code.writeShort(cp_getString(methods[methodIdx].getName()));
0840:
0841:                code.writeByte(INVOKEVT); // invokevirtual processEvent()
0842:                code.writeShort(cp_processEvent);
0843:
0844:                exEndPC = code.size();
0845:
0846:                // [4] Handle any exceptions thrown by processEvent():
0847:                //
0848:                //     catch (Throwable exception) {
0849:                //	       ....
0850:                //     }
0851:                //
0852:                //	   Note, we use WIDE version of load/store in all subsequent
0853:                //	   byte codes so that it's easy to calculate the offset
0854:                //	   for jumping to the "normal" return statement.)
0855:
0856:                Class exceptions[] = methods[methodIdx].getExceptionTypes();
0857:
0858:                int offset = 5 + 4 + exceptions.length * 18 + 4;
0859:                code.writeByte(GOTO_W); // goto_w	#<offset>
0860:                code.writeInt(offset);
0861:
0862:                exHandlerPC = code.size();
0863:
0864:                code.writeByte(WIDE); // astore	exception
0865:                code.writeByte(ASTORE);
0866:                code.writeShort(exceptionVarIdx);
0867:
0868:                for (int i = 0; i < exceptions.length; i++) {
0869:                    // Write the exception handler for each of the checked exception
0870:                    // types. Each handler is 16 bytes long.
0871:
0872:                    code.writeByte(WIDE); // aload	exception
0873:                    code.writeByte(ALOAD);
0874:                    code.writeShort(exceptionVarIdx);
0875:
0876:                    code.writeByte(INSTNCOF); // instanceof	<exceptions[i]>
0877:                    code.writeShort(cp_getClass(exceptions[i]));
0878:
0879:                    code.writeByte(IFEQ); // ifeq		#<nextException>
0880:                    code.writeShort(11);
0881:
0882:                    code.writeByte(WIDE); // aload	exception
0883:                    code.writeByte(ALOAD);
0884:                    code.writeShort(exceptionVarIdx);
0885:
0886:                    code.writeByte(CHKCAST); // checkcast	<exceptions[i]>
0887:                    code.writeShort(cp_getClass(exceptions[i]));
0888:
0889:                    code.writeByte(ATHROW); // athrow
0890:                }
0891:
0892:                code.writeByte(ALOAD_0); // aload_0	this
0893:
0894:                code.writeByte(INVOKEVT); // invokevirtual _wrongExceptionError()
0895:                code.writeShort(cp_wrongException);
0896:
0897:                // [5] Normal return from this method.
0898:
0899:                Class retType = methods[methodIdx].getReturnType();
0900:
0901:                if (retType == Void.TYPE) {
0902:                    code.writeByte(RETURN);
0903:                } else if (retType.isPrimitive()) {
0904:                    code.writeByte(ALOAD_0); // aload_0	this
0905:
0906:                    code.writeByte(INVOKEVT); // invokevirtual return_<type>
0907:                    code.writeShort(cp_getReturnMethodRef(retType));
0908:
0909:                    if (retType == Double.TYPE) {
0910:                        code.writeByte(DRETURN); // dreturn
0911:                    } else if (retType == Float.TYPE) {
0912:                        code.writeByte(FRETURN); // freturn
0913:                    } else if (retType == Long.TYPE) {
0914:                        code.writeByte(LRETURN); // lreturn
0915:                    } else {
0916:                        // IRETURN is used for boolean,
0917:                        // byte, char, int and short.
0918:
0919:                        code.writeByte(IRETURN); // ireturn
0920:                    }
0921:                } else {
0922:                    code.writeByte(ALOAD_0); // aload_0	this
0923:
0924:                    code.writeByte(LDC_W); // ldc_w	<retType.getName()>
0925:                    code.writeShort(cp_getString(retType.getName()));
0926:
0927:                    code.writeByte(INVOKEVT); // invokevirtual return_<type>
0928:                    code.writeShort(cp_getReturnMethodRef(retType));
0929:
0930:                    code.writeByte(CHKCAST); // checkcast <retType>
0931:                    code.writeShort(cp_getClass(retType));
0932:                    code.writeByte(ARETURN); // areturn
0933:                }
0934:
0935:                int codeLength = code.size();
0936:
0937:                // [6] Write the exception table: we catch all Throwable
0938:                //     classes.
0939:
0940:                code.writeShort(1); // exception_table_length
0941:
0942:                code.writeShort(exStartPC); // start_pc
0943:                code.writeShort(exEndPC); // end_pc
0944:                code.writeShort(exHandlerPC); // handler_pc
0945:                code.writeShort( // catch_type
0946:                        cp_getClass(Throwable.class));
0947:
0948:                // [7] The attributes table (empty)
0949:
0950:                code.writeShort(0); // attribute_count
0951:
0952:                // [8] Now we are done. Emit the code section into the output
0953:                //     stream.
0954:
0955:                code.close();
0956:                byte codeBytes[] = baos.toByteArray();
0957:
0958:                ostream.writeShort(cp_code); // attr_name_index = "Code"
0959:                ostream.writeInt(codeBytes.length // attr_length
0960:                        + 8);
0961:
0962:                ostream.writeShort(max_stacks);
0963:                ostream.writeShort(max_locals);
0964:
0965:                ostream.writeInt(codeLength); // code_length
0966:                ostream.write(codeBytes);
0967:            }
0968:
0969:            /*
0970:             *----------------------------------------------------------------------
0971:             *
0972:             * internalClassName --
0973:             *
0974:             *	Returns the "internal" class name of a Java class: E.g. the
0975:             *	internal name for "java.lang.Integer" is "java/lang/Integer".
0976:             *
0977:             * Results:
0978:             *	The "internal" class name.
0979:             *
0980:             * Side effects:
0981:             *	None.
0982:             *
0983:             *----------------------------------------------------------------------
0984:             */
0985:
0986:            private final static String internalClassName(String className) // "Normal" name of the class.
0987:            {
0988:                return className.replace('.', '/');
0989:            }
0990:
0991:            /*
0992:             *----------------------------------------------------------------------
0993:             *
0994:             * hashPutShort --
0995:             *
0996:             *	Puts a short value into a hash table.
0997:             *
0998:             * Results:
0999:             *	None.
1000:             *
1001:             * Side effects:
1002:             *	The short value is wrapped in a Short object and stored in the
1003:             *	hashtable.
1004:             *
1005:             *----------------------------------------------------------------------
1006:             */
1007:
1008:            private final static void hashPutShort(Hashtable hashtable, // The hashtable.
1009:                    Object key, // The key.
1010:                    short num) // Put this number under the given key
1011:            // in the hashtable.
1012:            {
1013:                Short shortObj = new Short(num);
1014:                hashtable.put(key, shortObj);
1015:            }
1016:
1017:            /*
1018:             *----------------------------------------------------------------------
1019:             *
1020:             * hashGetShort --
1021:             *
1022:             *	Gets the short value corresponding to the key from the hash
1023:             *	table.
1024:             *
1025:             * Results:
1026:             *	The short value corresponding to the key.
1027:             *
1028:             * Side effects:
1029:             *	None.
1030:             *
1031:             *----------------------------------------------------------------------
1032:             */
1033:
1034:            private final static short hashGetShort(Hashtable hashtable, // The hashtable.
1035:                    Object key) // The key.
1036:            {
1037:                return ((Short) hashtable.get(key)).shortValue();
1038:            }
1039:
1040:            /*
1041:             *----------------------------------------------------------------------
1042:             *
1043:             * getWrapperClass --
1044:             *
1045:             *	Given a primitive type (e.g. int), returns its wrapper class
1046:             *	(e.g., java.lang.Integer).
1047:             *
1048:             * Results:
1049:             *	The wrapper class for the primitive type.
1050:             *
1051:             * Side effects:
1052:             *	None.
1053:             *
1054:             *----------------------------------------------------------------------
1055:             */
1056:
1057:            private final static Class getWrapperClass(Class primType) // The Class object that represents the
1058:            // primitive type.
1059:            {
1060:                if (primType == Boolean.TYPE) {
1061:                    return Boolean.class;
1062:                } else if (primType == Byte.TYPE) {
1063:                    return Byte.class;
1064:                } else if (primType == Character.TYPE) {
1065:                    return Character.class;
1066:                } else if (primType == Double.TYPE) {
1067:                    return Double.class;
1068:                } else if (primType == Float.TYPE) {
1069:                    return Float.class;
1070:                } else if (primType == Integer.TYPE) {
1071:                    return Integer.class;
1072:                } else if (primType == Long.TYPE) {
1073:                    return Long.class;
1074:                } else {
1075:                    return Short.class;
1076:                }
1077:            }
1078:
1079:            /*
1080:             *----------------------------------------------------------------------
1081:             *
1082:             * getTypeDesc --
1083:             *
1084:             *	Returns the string that represents a Java type. E.g, "Z" for
1085:             *	boolean, "Lfoo.Bar;" for foo.Bar.
1086:             *
1087:             * Results:
1088:             *	The string that represents a Java type.
1089:             *
1090:             * Side effects:
1091:             *	None.
1092:             *
1093:             *----------------------------------------------------------------------
1094:             */
1095:
1096:            private final static String getTypeDesc(Class cls) {
1097:                if (cls.isPrimitive()) {
1098:                    if (cls == Boolean.TYPE) {
1099:                        return "Z";
1100:                    } else if (cls == Byte.TYPE) {
1101:                        return "B";
1102:                    } else if (cls == Character.TYPE) {
1103:                        return "C";
1104:                    } else if (cls == Double.TYPE) {
1105:                        return "D";
1106:                    } else if (cls == Float.TYPE) {
1107:                        return "F";
1108:                    } else if (cls == Integer.TYPE) {
1109:                        return "I";
1110:                    } else if (cls == Long.TYPE) {
1111:                        return "J";
1112:                    } else if (cls == Short.TYPE) {
1113:                        return "S";
1114:                    } else {
1115:                        return "V";
1116:                    }
1117:                } else {
1118:                    if (cls.isArray()) {
1119:                        return "[" + getTypeDesc(cls.getComponentType());
1120:                    } else {
1121:                        String s = "L" + cls.getName() + ";";
1122:                        return s.replace('.', '/');
1123:                    }
1124:                }
1125:            }
1126:
1127:            /*
1128:             *----------------------------------------------------------------------
1129:             *
1130:             * getMethodDesc --
1131:             *
1132:             *	Returns the string that represents the type of a method. E.g.
1133:             *	"(Lfoo.Bar;DI)V" for void xxx(foo.Bar,double,int)
1134:             *
1135:             * Results:
1136:             *	The string that represents the type of a method.
1137:             *
1138:             * Side effects:
1139:             *	None.
1140:             *
1141:             *----------------------------------------------------------------------
1142:             */
1143:
1144:            private final static String getMethodDescriptor(Method method) // Returns the desc of this method.
1145:            {
1146:                StringBuffer sbuf = new StringBuffer();
1147:                sbuf.append('(');
1148:
1149:                Class params[] = method.getParameterTypes();
1150:
1151:                for (int i = 0; i < params.length; i++) {
1152:                    sbuf.append(getTypeDesc(params[i]));
1153:                }
1154:                sbuf.append(')');
1155:                sbuf.append(getTypeDesc(method.getReturnType()));
1156:
1157:                return sbuf.toString();
1158:            }
1159:
1160:            /*
1161:             *----------------------------------------------------------------------
1162:             *
1163:             * writeLoadStore --
1164:             *
1165:             *	Writes the byte-code for a load or store operation. To reduce
1166:             *	the size of the byte code, the WIDE prefix is used only when
1167:             *	necessary (i.e., the address is greater than 255)
1168:             *
1169:             * Results:
1170:             *	None.
1171:             *
1172:             * Side effects:
1173:             *	the load/store byte codes are written into the
1174:             *	DataOutputStream.
1175:             *
1176:             *----------------------------------------------------------------------
1177:             */
1178:
1179:            void writeLoadStore(DataOutputStream code, // The DataOutputStream to write the byte-code
1180:                    // into.
1181:                    int opcode, // The opcode can be ?LOAD or ?STORE
1182:                    int address) // The target address of the load/store.
1183:                    throws IOException // This exception may never happen. We
1184:            // declare it just to avoid putting
1185:            // catch statements everywhere.
1186:            {
1187:                if (address > 255) {
1188:                    code.writeByte(WIDE);
1189:                    code.writeByte(opcode);
1190:                    code.writeShort(address);
1191:                } else {
1192:                    code.writeByte(opcode);
1193:                    code.writeByte(address);
1194:                }
1195:            }
1196:
1197:            /*
1198:             *----------------------------------------------------------------------
1199:             *
1200:             * cp_putUtf8 --
1201:             *
1202:             *	Puts a UTF8 string into the constant pool.
1203:             *
1204:             * Results:
1205:             *	The index of that UTF8 string in the constant pool.
1206:             *
1207:             * Side effects:
1208:             *	The UTF8 string is put into the constPool vector if the same
1209:             *	string is not already in the constant pool.
1210:             *
1211:             *----------------------------------------------------------------------
1212:             */
1213:
1214:            short cp_putUtf8(String string) // The string to put (in UTF8 format) into
1215:            // the constant pool.
1216:            {
1217:                Short shortObj;
1218:
1219:                shortObj = (Short) utf8Tab.get(string);
1220:
1221:                // Check to make sure that the string is not already in the
1222:                // constant pool so that we won't have duplicated entries (which
1223:                // wastes space!).
1224:
1225:                if (shortObj != null) {
1226:                    return shortObj.shortValue();
1227:                } else {
1228:                    ConstUtf cutf = new ConstUtf();
1229:                    cutf.string = string;
1230:                    constPool.addElement(cutf);
1231:
1232:                    short id = (short) cpSize++;
1233:                    hashPutShort(utf8Tab, string, id);
1234:                    return id;
1235:                }
1236:            }
1237:
1238:            /*
1239:             *----------------------------------------------------------------------
1240:             *
1241:             * cp_putString --
1242:             *
1243:             *	Puts a string into the constant pool. N.B., this is stored as
1244:             *	a CONSTANT_String element. In contrast, UTF8 strings are
1245:             *	stored as CONSTANT_Utf8. Read "The Java Virtual Machine
1246:             *	Specification" for details.
1247:             *
1248:             * Results:
1249:             *	The index of the string in the constant pool.
1250:             *
1251:             * Side effects:
1252:             *	The string is put into the constPool vector.
1253:             *
1254:             *----------------------------------------------------------------------
1255:             */
1256:
1257:            private short cp_putString(String string) // The string to put (in CONSTANT_String
1258:            // format) into the constant pool.
1259:            {
1260:                ConstString cstr = new ConstString();
1261:                cstr.string_index = cp_putUtf8(string);
1262:                constPool.addElement(cstr);
1263:
1264:                short id = (short) cpSize++;
1265:                hashPutShort(stringRef, string, id);
1266:                return id;
1267:            }
1268:
1269:            /*
1270:             *----------------------------------------------------------------------
1271:             *
1272:             * cp_putClass --
1273:             *
1274:             *	Puts a CONSTANT_Class element into the constant pool.
1275:             *
1276:             * Results:
1277:             *	The index of the class.
1278:             *
1279:             * Side effects:
1280:             *	The class is put into the constPool vector.
1281:             *
1282:             *----------------------------------------------------------------------
1283:             */
1284:
1285:            private short cp_putClass(String className) // Fully qualified name of the class.
1286:            {
1287:                ConstClass ccls = new ConstClass();
1288:                ccls.name_index = cp_putUtf8(internalClassName(className));
1289:                constPool.addElement(ccls);
1290:
1291:                return (short) cpSize++;
1292:            }
1293:
1294:            /*
1295:             *----------------------------------------------------------------------
1296:             *
1297:             * cp_putNameAndType --
1298:             *
1299:             *	Puts a CONSTANT_NameAndType element into the constant pool.
1300:             *
1301:             * Results:
1302:             *	The index of the NameAndType.
1303:             *
1304:             * Side effects:
1305:             *	The NameAndType is put into the constPool vector.
1306:             *
1307:             *----------------------------------------------------------------------
1308:             */
1309:
1310:            short cp_putNameAndType(String name, // The name of the method.
1311:                    String type) // The type of the method.
1312:            {
1313:                ConstNameAndType cnat = new ConstNameAndType();
1314:                cnat.name_index = cp_putUtf8(name);
1315:                cnat.desc_index = cp_putUtf8(type);
1316:                constPool.addElement(cnat);
1317:
1318:                return (short) cpSize++;
1319:            }
1320:
1321:            /*
1322:             *----------------------------------------------------------------------
1323:             *
1324:             * cp_putMethodRef --
1325:             *
1326:             *	Puts a CONSTANT_MethodRef element into the constant pool.
1327:             *
1328:             * Results:
1329:             *	The index of the MethodRef.
1330:             *
1331:             * Side effects:
1332:             *	The MethodRef is put into the constPool vector.
1333:             *
1334:             *----------------------------------------------------------------------
1335:             */
1336:
1337:            short cp_putMethodRef(short class_index, // Index of the class.
1338:                    String name, // Name of the method.
1339:                    String desc) // Descriptor of the method.
1340:            {
1341:                ConstMethodRef cmref = new ConstMethodRef();
1342:                cmref.class_index = class_index;
1343:                cmref.name_and_type_index = cp_putNameAndType(name, desc);
1344:
1345:                constPool.addElement(cmref);
1346:
1347:                return (short) cpSize++;
1348:            }
1349:
1350:            /*
1351:             *----------------------------------------------------------------------
1352:             *
1353:             * cp_putMethodDesc --
1354:             *
1355:             *	Puts the UTF8 strings needed to describe a method defined in
1356:             *	the generated class.
1357:             *
1358:             * Results:
1359:             *	A MethodDesc object that contains the index of the name and
1360:             *	descriptor of the method.
1361:             *
1362:             * Side effects:
1363:             *	UTF8 strings may be put into the constPool vector.
1364:             *
1365:             *----------------------------------------------------------------------
1366:             */
1367:
1368:            MethodDesc cp_putMethodDesc(String name, // Name of the method.
1369:                    String descriptor, // Descriptor of the method. 
1370:                    boolean generateID) // True if we need to generate a string ID
1371:            // to pass to _processEvent() for this method.
1372:            {
1373:                MethodDesc desc = new MethodDesc();
1374:                desc.name_index = cp_putUtf8(name);
1375:                desc.descriptor_index = cp_putUtf8(descriptor);
1376:                if (generateID) {
1377:                    cp_putString(name);
1378:                }
1379:
1380:                return desc;
1381:            }
1382:
1383:            /*
1384:             *----------------------------------------------------------------------
1385:             *
1386:             * cp_getClass --
1387:             *
1388:             *	Returns the index of a class definition in the constant pool
1389:             *
1390:             * Results:
1391:             *	The index of the class definition.
1392:             *
1393:             * Side effects:
1394:             *	None.
1395:             *
1396:             *----------------------------------------------------------------------
1397:             */
1398:
1399:            short cp_getClass(Class cls) // Query the index of this class.
1400:            {
1401:                return hashGetShort(clsRef, cls);
1402:            }
1403:
1404:            /*
1405:             *----------------------------------------------------------------------
1406:             *
1407:             * cp_getString --
1408:             *
1409:             *	Returns the index of a CONSTANT_String definition in the
1410:             *	constant pool
1411:             *
1412:             * Results:
1413:             *	The index of the string.
1414:             *
1415:             * Side effects:
1416:             *	None.
1417:             *
1418:             *----------------------------------------------------------------------
1419:             */
1420:
1421:            short cp_getString(String string) // Query the index of this string.
1422:            {
1423:                return hashGetShort(stringRef, string);
1424:            }
1425:
1426:            /*
1427:             *----------------------------------------------------------------------
1428:             *
1429:             * cp_getWrapperConstructor --
1430:             *
1431:             *	Returns the constant pool index of a CONSTANT_MethodRef
1432:             *	definition for the constructor of the primitive wrapper class.
1433:             *
1434:             * Results:
1435:             *	The index of the constructor.
1436:             *
1437:             * Side effects:
1438:             *	None.
1439:             *
1440:             *----------------------------------------------------------------------
1441:             */
1442:
1443:            short cp_getWrapperConstructor(Class primType) // Query the index of the constructor
1444:            // of the wrapper class of this primitive type.
1445:            {
1446:                return hashGetShort(wrapperConsRef, primType);
1447:            }
1448:
1449:            /*
1450:             *----------------------------------------------------------------------
1451:             *
1452:             * cp_getReturnMethodRef --
1453:             *
1454:             *	Returns the constant pool index of a CONSTANT_MethodRef
1455:             *	definition of methods such super._return_int(); these methods
1456:             *	are used to return values from the binding script.
1457:             *
1458:             * Results:
1459:             *	The index of the method.
1460:             *
1461:             * Side effects:
1462:             *	None.
1463:             *
1464:             *----------------------------------------------------------------------
1465:             */
1466:
1467:            short cp_getReturnMethodRef(Class retType) // Query the index of the method that
1468:            // returns this type.
1469:            {
1470:                if (retType.isPrimitive()) {
1471:                    return hashGetShort(returnMethodRef, retType);
1472:                } else {
1473:                    return hashGetShort(returnMethodRef, Object.class);
1474:                }
1475:            }
1476:
1477:            // The following five inner classes are used to store temporary copies
1478:            // of constane pool items in a Vector.
1479:
1480:            class ConstUtf {
1481:                String string; // The string to put into the constant pool
1482:                // in UTF8 format.
1483:            }
1484:
1485:            class ConstString {
1486:                short string_index; // Index of the CONSTANR_Utf8 element that
1487:                // defines the string.
1488:            }
1489:
1490:            class ConstClass {
1491:                short name_index; // Index of the CONSTANR_Utf8 element that
1492:                // defines the internal name of the class.
1493:            }
1494:
1495:            class ConstNameAndType {
1496:                short name_index; // Index of the CONSTANR_Utf8 element that
1497:                // defines the name of a method.
1498:                short desc_index; // Index of the CONSTANR_Utf8 element that
1499:                // defines the type of a method.
1500:            }
1501:
1502:            class ConstMethodRef {
1503:                short class_index; // Index of the CONSTANR_Utf8 element that
1504:                // defines the internal name of the class.
1505:                short name_and_type_index; // Index of the CONSTANR_NameAndType element
1506:                // that defines the name and type of the
1507:                // method.
1508:            }
1509:
1510:            // This inner class stores the name and descriptor of the method to
1511:            // generate.
1512:
1513:            class MethodDesc {
1514:
1515:                // Index to the name of the method (a CONSTANT_String).
1516:
1517:                short name_index;
1518:
1519:                // Index to the name of the method (a CONSTANT_String).
1520:
1521:                short descriptor_index;
1522:
1523:            } // end AdaptorGen.MethodDesc
1524:
1525:        } // end AdaptorGen
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.