Source Code Cross Referenced for ProxyAssembler.java in  » EJB-Server-JBoss-4.2.1 » server » org » jboss » proxy » compiler » 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 » EJB Server JBoss 4.2.1 » server » org.jboss.proxy.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.proxy.compiler;
023:
024:        import java.lang.reflect.*;
025:        import java.util.*;
026:        import java.io.*;
027:
028:        /**
029:         * A simple bytecode assembler.
030:         *
031:         * @deprecated Use {@link ProxyCompiler} or Jakarta BCEL instead.
032:         *
033:         * @author Unknown
034:         * @version $Revision: 57209 $
035:         */
036:        public class ProxyAssembler {
037:            // constant pool:
038:            Vector cv = new Vector();
039:            Hashtable ct = new Hashtable();
040:            Hashtable ut = new Hashtable();
041:            short cn = 1;
042:
043:            // members:
044:            Vector members;
045:            AMember current;
046:            ByteArrayOutputStream code; // current.code
047:            Stack stack; // current.stack
048:
049:            // other info:
050:            String className;
051:            int modifiers;
052:            Class super Class;
053:            Class interfaces[];
054:
055:            public short getIndex(Object x) {
056:                Object n = ct.get(x);
057:                if (n == null) {
058:                    n = new Short(cn++);
059:                    ct.put(x, n);
060:                    cv.addElement(x);
061:                }
062:                return ((Short) n).shortValue();
063:            }
064:
065:            public short getUtfIndex(String x) {
066:                Object n = ut.get(x);
067:                if (n == null) {
068:                    n = new Short(cn++);
069:                    ut.put(x, n);
070:                    int xlen = 2 + x.length(); // x.utfLength(), really
071:                    ByteArrayOutputStream bytes = new ByteArrayOutputStream(
072:                            xlen);
073:                    DataOutputStream ds = new DataOutputStream(bytes);
074:                    try {
075:                        ds.writeByte(CONSTANT_UTF8);
076:                        ds.writeUTF(x);
077:                    } catch (IOException ee) {
078:                        throw new RuntimeException(ee.toString());
079:                    }
080:                    cv.addElement(bytes.toByteArray());
081:                }
082:                return ((Short) n).shortValue();
083:            }
084:
085:            public short getNTIndex(String name, String sig) {
086:                NameAndType nt = new NameAndType();
087:                nt.name = getUtfIndex(name);
088:                nt.sig = getUtfIndex(sig);
089:                return getIndex(nt);
090:            }
091:
092:            public short getClassIndex(Class c) {
093:                short ci = getUtfIndex(c.getName().replace('.', '/'));
094:                short data[] = { CONSTANT_CLASS, ci };
095:                return getIndex(data);
096:            }
097:
098:            public short getMemberIndex(Object cls, String name, Class ptypes[]) {
099:                if (cls instanceof  Class) {
100:                    Class c = (Class) cls;
101:                    Member m;
102:                    try {
103:                        if (ptypes == null) {
104:                            m = c.getField(name);
105:                        } else if (name.equals("<init>")) {
106:                            m = c.getConstructor(ptypes);
107:                        } else {
108:                            m = c.getMethod(name, ptypes);
109:                        }
110:                    } catch (NoSuchMethodException ee) {
111:                        throw new IllegalArgumentException(ee + " in " + c);
112:                    } catch (NoSuchFieldException ee) {
113:                        throw new IllegalArgumentException(ee + " in " + c);
114:                    }
115:                    return getIndex(m);
116:                } else if (cls instanceof  ProxyAssembler) {
117:                    ProxyAssembler asm = (ProxyAssembler) cls;
118:                    String sig = getSig(null, ptypes);
119:                    AMember m = asm.findMember(sig, name);
120:                    if (m == null) {
121:                        throw new IllegalArgumentException(sig + " " + name);
122:                    }
123:                    return getIndex(m);
124:                } else {
125:                    throw new IllegalArgumentException("not a type: " + cls);
126:                }
127:            }
128:
129:            public short getMemberIndex(Object cls, String name) {
130:                return getMemberIndex(cls, name, null);
131:            }
132:
133:            public static String getSig(Class t) {
134:                if (t == null) {
135:                    return "";
136:                } else if (t.isPrimitive()) {
137:                    if (false) {
138:                        return "";
139:                    } else if (t == Boolean.TYPE) {
140:                        return "Z";
141:                    } else if (t == Character.TYPE) {
142:                        return "C";
143:                    } else if (t == Byte.TYPE) {
144:                        return "B";
145:                    } else if (t == Short.TYPE) {
146:                        return "S";
147:                    } else if (t == Integer.TYPE) {
148:                        return "I";
149:                    } else if (t == Long.TYPE) {
150:                        return "J";
151:                    } else if (t == Float.TYPE) {
152:                        return "F";
153:                    } else if (t == Double.TYPE) {
154:                        return "D";
155:                    } else if (t == Void.TYPE) {
156:                        return "V";
157:                    } else {
158:                        Class a = java.lang.reflect.Array.newInstance(t, 0)
159:                                .getClass();
160:                        return getSig(a).substring(1);
161:                    }
162:                } else if (t.isArray()) {
163:                    return t.getName().replace('.', '/');
164:                } else {
165:                    return "L" + t.getName().replace('.', '/') + ";";
166:                }
167:            }
168:
169:            public static String getSig(Class rt, Class pt[]) {
170:                if (pt == null) {
171:                    return getSig(rt);
172:                }
173:                StringBuffer sb = new StringBuffer();
174:                sb.append("(");
175:                for (int i = 0; i < pt.length; i++) {
176:                    sb.append(getSig(pt[i]));
177:                }
178:                sb.append(")");
179:                sb.append(getSig(rt));
180:                return sb.toString();
181:            }
182:
183:            boolean isInterface() {
184:                return Modifier.isInterface(modifiers);
185:            }
186:
187:            public ProxyAssembler(String className, int modifiers,
188:                    Class super Class, Class interfaces[]) {
189:                if (interfaces == null)
190:                    interfaces = new Class[0];
191:                this .className = className;
192:                this .modifiers = modifiers;
193:                this .super Class = super Class;
194:                this .interfaces = interfaces;
195:                cv.addElement(null); // the first cpool entry is unused
196:                members = new Vector();
197:                addMember(0, "", null, "");
198:            }
199:
200:            private static class AMember {
201:                int mods;
202:                int sp;
203:                int spmax;
204:                int locmax;
205:                int index;
206:                Class type; // field or method return type
207:                String sig;
208:                String name;
209:                Vector attr;
210:                Stack stack;
211:                ByteArrayOutputStream code;
212:                ProxyAssembler asm;
213:            }
214:
215:            private static class Attr {
216:                String name;
217:                Object data;
218:            }
219:
220:            private static class AValue { // found in the stack
221:                int num;
222:                Object type;
223:            }
224:
225:            private static class NameAndType {
226:                short name;
227:                short sig;
228:
229:                // must act as a hashtable key:
230:                public boolean equals(Object x) {
231:                    if (x instanceof  NameAndType) {
232:                        NameAndType that = (NameAndType) x;
233:                        return that.name == name && that.sig == sig;
234:                    }
235:                    return false;
236:                }
237:
238:                public int hashCode() {
239:                    return name + sig * 1000;
240:                }
241:            }
242:
243:            public Object getCurrentMember() {
244:                return current;
245:            }
246:
247:            public void setCurrentMember(Object m) {
248:                if (m == null) {
249:                    m = members.elementAt(0);
250:                }
251:                current = (AMember) m;
252:                code = current.code;
253:                stack = current.stack;
254:            }
255:
256:            AMember findMember(String sig, String name) {
257:                for (int i = 0; i < members.size(); i++) {
258:                    AMember m = (AMember) members.elementAt(i);
259:                    if (m.name.equals(name)) {
260:                        if (!sig.startsWith("(") ? !m.sig.startsWith("(")
261:                                : m.sig.startsWith(sig)) {
262:                            return m;
263:                        }
264:                    }
265:                }
266:                return null;
267:            }
268:
269:            void addExceptionAttribute(Class[] classes) {
270:                try {
271:
272:                    if ((classes == null) || (classes.length == 0))
273:                        return;
274:
275:                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
276:                    DataOutputStream dos = new DataOutputStream(baos);
277:                    short count = (short) classes.length;
278:                    dos.writeShort(count);
279:                    for (int iter = 0; iter < classes.length; iter++) {
280:                        dos.writeShort(getClassIndex(classes[iter]));
281:                    }
282:                    dos.flush();
283:                    baos.flush();
284:                    addAttribute("Exception", baos.toByteArray());
285:                } catch (IOException cantHappen) {
286:                    cantHappen.printStackTrace();
287:                }
288:            }
289:
290:            AMember addMember(int mods, String sig, Class[] exceptionClasses,
291:                    String name) {
292:                String qsig = sig.substring(0, 1 + sig.indexOf(')'));
293:                AMember m = findMember(qsig, name);
294:                if (m != null) {
295:                    setCurrentMember(m);
296:                    current.mods |= mods;
297:                    modifiers |= (mods & Modifier.ABSTRACT);
298:                    return m;
299:                }
300:                m = new AMember();
301:                m.asm = this ;
302:                if (isMethodSig(sig)) {
303:                    m.code = new ByteArrayOutputStream();
304:                    m.stack = new Stack();
305:                }
306:                m.sig = sig;
307:                m.name = name;
308:                m.attr = new Vector();
309:                m.index = members.size();
310:                m.mods = mods;
311:                members.addElement(m);
312:                setCurrentMember(m);
313:                this .addExceptionAttribute(exceptionClasses);
314:                return m;
315:            }
316:
317:            public Object addMember(int mods, Class rtype, String name,
318:                    Class ptypes[], Class[] exceptionClasses) {
319:                AMember m = addMember(mods, getSig(rtype, ptypes),
320:                        exceptionClasses, name);
321:                if (ptypes != null && stack.size() == 0) {
322:                    // push the arguments onto the stack
323:                    if (!Modifier.isStatic(mods)) {
324:                        declare(this );
325:                    }
326:                    for (int i = 0; i < ptypes.length; i++) {
327:                        declare(ptypes[i]);
328:                    }
329:                }
330:                m.type = rtype;
331:                this .addExceptionAttribute(exceptionClasses);
332:                return m;
333:            }
334:
335:            public Object addMember(int mods, Class type,
336:                    Class[] exceptionClasses, String name) {
337:                return addMember(mods, type, name, null, exceptionClasses);
338:            }
339:
340:            public void addAttribute(AMember m, String name, Object data) {
341:                if (m == null) {
342:                    m = (AMember) members.elementAt(0);
343:                }
344:                Attr a = new Attr();
345:                a.name = name;
346:                a.data = data;
347:                m.attr.addElement(a);
348:            }
349:
350:            public void addAttribute(String name, Object data) {
351:                addAttribute(current, name, data);
352:            }
353:
354:            // instruction emitters
355:            private final static int opc_iconst_0 = 3, opc_bipush = 16,
356:                    opc_sipush = 17, opc_ldc = 18, opc_ldc_w = 19,
357:                    opc_ldc2_w = 20, opc_aaload = 50, opc_aastore = 83,
358:                    opc_dup = 89, opc_getfield = 180, field_put = 1,
359:                    field_static = -2, opc_invokevirtual = 182,
360:                    opc_invokespecial = 183, opc_invokestatic = 184,
361:                    opc_invokeinterface = 185, opc_new = 187,
362:                    opc_newarray = 188, opc_anewarray = 189, opc_aload = 25,
363:                    opc_aload_0 = 42, opc_wide = 196, opc_areturn = 176,
364:                    opc_return = 177, opc_checkcast = 192, kind_a = 0,
365:                    kind_i = -4, kind_l = -3, kind_f = -2, kind_d = -1,
366:                    kind_b = 1, kind_c = 2, kind_s = 3;
367:
368:            public int declare(Object t) {
369:                int n = current.sp;
370:                current.sp += 1;
371:                if (t == Double.TYPE || t == Long.TYPE) {
372:                    current.sp += 1;
373:                }
374:                if (current.spmax < current.sp) {
375:                    current.spmax = current.sp;
376:                }
377:                AValue se = new AValue();
378:                se.num = n;
379:                se.type = t;
380:                stack.push(se);
381:                return stack.size() - 1;
382:            }
383:
384:            public void undeclare(Object t) {
385:                AValue se = (AValue) stack.pop();
386:                current.sp = se.num;
387:            }
388:
389:            public void pushConstant(Object x) {
390:                int op = opc_ldc_w;
391:                if (x instanceof  Integer) {
392:                    declare(Integer.TYPE);
393:                    int v = ((Integer) x).intValue();
394:                    if (v >= -1 && v <= 5) {
395:                        code.write(opc_iconst_0 + v);
396:                        return;
397:                    } else if ((v > -(1 << 7)) && (v < (1 << 7))) {
398:                        code.write(opc_bipush);
399:                        code.write(v);
400:                        return;
401:                    } else if ((v > -(1 << 15)) && (v < (1 << 15))) {
402:                        code.write(opc_sipush);
403:                        codeShort(v);
404:                        return;
405:                    }
406:                } else if (x instanceof  Float) {
407:                    declare(Float.TYPE);
408:                } else if (x instanceof  String) {
409:                    declare(String.class);
410:                } else if (x instanceof  Long) {
411:                    declare(Long.TYPE);
412:                    op = opc_ldc2_w;
413:                } else if (x instanceof  Double) {
414:                    declare(Double.TYPE);
415:                    op = opc_ldc2_w;
416:                } else {
417:                    throw new RuntimeException("unexpected: " + x);
418:                }
419:                int xi = getIndex(x);
420:                if (op == opc_ldc_w && xi < (1 << 8)) {
421:                    code.write(opc_ldc);
422:                    code.write(xi);
423:                } else {
424:                    code.write(op);
425:                    codeShort(xi);
426:                }
427:            }
428:
429:            public void pushConstant(int x) {
430:                pushConstant(new Integer(x));
431:            }
432:
433:            public int pushLocal(int loc) {
434:                if (current.locmax < loc) {
435:                    current.locmax = loc;
436:                }
437:                AValue se = (AValue) stack.elementAt(loc);
438:                int kind = typeKind(se.type, false);
439:                if (se.num <= 3) {
440:                    code.write(opc_aload_0 + (kind * 4) + se.num);
441:                } else {
442:                    codeWide(opc_aload + kind, se.num);
443:                }
444:                return declare(se.type);
445:            }
446:
447:            public int dup() {
448:                code.write(opc_dup);
449:                return declare(stack.peek());
450:            }
451:
452:            public void checkCast(Object t) {
453:                code.write(opc_checkcast);
454:                codeShort(getIndex(t));
455:                AValue se = (AValue) stack.pop();
456:                if (se.type instanceof  Class && ((Class) se.type).isPrimitive()) {
457:                    undeclare(Object.class); // get an error
458:                    declare(t);
459:                }
460:                se.type = t;
461:            }
462:
463:            public int pushNewArray(Object etype) {
464:                int kind = typeKind(etype, true);
465:                int tcode;
466:                Class t;
467:                switch (kind) {
468:                case kind_a:
469:                    code.write(opc_anewarray);
470:                    codeShort(getIndex(etype));
471:                    return declare(Object[].class);
472:                case kind_f:
473:                    tcode = 0x00000006;
474:                    t = float[].class;
475:                    break;
476:                case kind_d:
477:                    tcode = 0x00000007;
478:                    t = double[].class;
479:                    break;
480:                case kind_i:
481:                    tcode = 0x0000000a;
482:                    t = int[].class;
483:                    break;
484:                case kind_l:
485:                    tcode = 0x0000000b;
486:                    t = long[].class;
487:                    break;
488:                case kind_b:
489:                    if (etype == Boolean.TYPE) {
490:                        tcode = 0x00000004;
491:                        t = boolean[].class;
492:                    } else {
493:                        tcode = 0x00000008;
494:                        t = byte[].class;
495:                    }
496:                    break;
497:                case kind_c:
498:                    tcode = 0x00000005;
499:                    t = char[].class;
500:                    break;
501:                case kind_s:
502:                    tcode = 0x00000009;
503:                    t = short[].class;
504:                    break;
505:                default:
506:                    return 0;
507:                }
508:                code.write(opc_newarray);
509:                code.write(tcode);
510:                return declare(t); // etype[]
511:            }
512:
513:            public void setElement(Object etype) {
514:                int kind = typeKind(etype, true);
515:                code.write(opc_aastore + kind);
516:                undeclare(etype);
517:                undeclare(Integer.TYPE);
518:                undeclare(null); // etype[]
519:            }
520:
521:            public void pushElement(Object etype) {
522:                int kind = typeKind(etype, true);
523:                code.write(opc_aaload + kind);
524:                undeclare(Integer.TYPE);
525:                undeclare(null); // etype[]
526:                declare(etype);
527:            }
528:
529:            public void ret() {
530:                if (current.sig.endsWith("V")) {
531:                    code.write(opc_return);
532:                    return;
533:                }
534:                Object t = current.type;
535:                undeclare(t);
536:                code.write(opc_areturn + typeKind(t, false));
537:                stack = null;
538:            }
539:
540:            private int dofield(Object cls, String name, boolean isPut) {
541:                int fi = getMemberIndex(cls, name);
542:                Object x = cv.elementAt(fi);
543:                int op = opc_getfield;
544:                int mod;
545:                Object t;
546:                if (x instanceof  Field) {
547:                    Field f = (Field) x;
548:                    mod = f.getModifiers();
549:                    t = f.getType();
550:                } else {
551:                    AMember m = (AMember) x;
552:                    mod = m.mods;
553:                    t = m.type;
554:                }
555:                if (isPut) {
556:                    op += field_put;
557:                    undeclare(t);
558:                }
559:                if (Modifier.isStatic(mod)) {
560:                    op += field_static;
561:                } else {
562:                    undeclare(cls);
563:                }
564:                code.write(op);
565:                codeShort(fi);
566:                return isPut ? -1 : declare(t);
567:            }
568:
569:            public int pushField(Object cls, String name) {
570:                return dofield(cls, name, false);
571:            }
572:
573:            public void setField(Object cls, String name) {
574:                dofield(cls, name, true);
575:            }
576:
577:            public int invoke(Object cls, String name, Class ptypes[]) {
578:                int mi = getMemberIndex(cls, name, ptypes);
579:                Object x = cv.elementAt(mi);
580:                int mod;
581:                Object rtype;
582:                int op = opc_invokevirtual;
583:                if (x instanceof  Method) {
584:                    Method m = (Method) x;
585:                    mod = m.getModifiers();
586:                    rtype = m.getReturnType();
587:                    if (m.getDeclaringClass().isInterface()) {
588:                        op = opc_invokeinterface;
589:                    }
590:                } else if (x instanceof  Constructor) {
591:                    Constructor m = (Constructor) x;
592:                    mod = m.getModifiers();
593:                    rtype = Void.TYPE;
594:                    op = opc_invokespecial;
595:                } else {
596:                    AMember m = (AMember) x;
597:                    mod = m.mods;
598:                    rtype = m.type;
599:                    if (m.asm.isInterface()) {
600:                        op = opc_invokeinterface;
601:                    }
602:                }
603:                if (Modifier.isStatic(mod)) {
604:                    op = opc_invokestatic;
605:                } else {
606:                    undeclare(cls);
607:                }
608:                for (int i = ptypes.length; --i >= 0;) {
609:                    undeclare(ptypes[i]);
610:                }
611:                code.write(op);
612:                codeShort(mi);
613:                return declare(rtype);
614:            }
615:
616:            private int typeKind(Object t, boolean subwords) {
617:                if (t != null && t instanceof  Class
618:                        && ((Class) t).isPrimitive()) {
619:                    if (t == Float.TYPE) {
620:                        return kind_f;
621:                    } else if (t == Long.TYPE) {
622:                        return kind_l;
623:                    } else if (t == Double.TYPE) {
624:                        return kind_d;
625:                    } else if (t == Integer.TYPE || !subwords) {
626:                        return kind_i;
627:                    } else if (t == Character.TYPE) {
628:                        return kind_c;
629:                    } else if (t == Short.TYPE) {
630:                        return kind_s;
631:                    } else {
632:                        return kind_b;
633:                    }
634:                } else {
635:                    return kind_a;
636:                }
637:            }
638:
639:            private void codeWide(int op, int n) {
640:                if (n < (1 << 8)) {
641:                    code.write(op);
642:                    code.write(n);
643:                } else {
644:                    code.write(opc_wide);
645:                    code.write(op);
646:                    codeShort(n);
647:                }
648:            }
649:
650:            private void codeShort(int v) {
651:                code.write(v >>> 8);
652:                code.write(v);
653:            }
654:
655:            private static boolean isMethodSig(String sig) {
656:                return (sig.indexOf('(') >= 0);
657:            }
658:
659:            public byte[] getCode() {
660:                try {
661:                    return internalGetCode();
662:                } catch (IOException ee) {
663:                    throw new RuntimeException(ee.toString());
664:                }
665:            }
666:
667:            public byte[] internalGetCode() throws IOException {
668:                // first, flush out all references to the cpool
669:                getIndex(this );
670:                getIndex(super Class);
671:                for (int i = 0; i < interfaces.length; i++) {
672:                    getIndex(interfaces[i]);
673:                }
674:                int nfields = 0;
675:                int nmethods = 0;
676:                for (int i = 0; i < members.size(); i++) {
677:                    AMember m = (AMember) members.elementAt(i);
678:
679:                    if (m.code != null) {
680:                        byte[] codeAttr = getMethodCode(m, m.code);
681:                        if (codeAttr != null) {
682:                            addAttribute(m, "Code", codeAttr);
683:                        }
684:                    }
685:
686:                    for (int j = 0; j < m.attr.size(); j++) {
687:                        Attr a = (Attr) m.attr.elementAt(j);
688:                        getUtfIndex(a.name);
689:                    }
690:
691:                    if (m.name.length() == 0) {
692:                        continue;
693:                    }
694:                    getUtfIndex(m.name);
695:                    getUtfIndex(m.sig);
696:                    if (isMethodSig(m.sig)) {
697:                        nmethods += 1;
698:                    } else {
699:                        nfields += 1;
700:                    }
701:                }
702:                // next, deal with internal references in the cpool
703:                for (int i = 0; i < cv.size(); i++) {
704:                    Object x = cv.elementAt(i);
705:                    if (x == null) {
706:                        continue;
707:                    } else if (x instanceof  String) {
708:                        String s = (String) x;
709:                        short si = getUtfIndex(s);
710:                        short data[] = { CONSTANT_STRING, si };
711:                        x = data;
712:                    } else if (x instanceof  Class) {
713:                        Class c = (Class) x;
714:                        short ci = getUtfIndex(c.getName().replace('.', '/'));
715:                        short data[] = { CONSTANT_CLASS, ci };
716:                        x = data;
717:                    } else if (x instanceof  Field) {
718:                        Field m = (Field) x;
719:                        short ci = getIndex(m.getDeclaringClass());
720:                        short nt = getNTIndex(m.getName(), getSig(m.getType()));
721:                        short data[] = { CONSTANT_FIELD, ci, nt };
722:                        x = data;
723:                    } else if (x instanceof  Constructor) {
724:                        Constructor m = (Constructor) x;
725:                        short ci = getIndex(m.getDeclaringClass());
726:                        short nt = getNTIndex("<init>", getSig(Void.TYPE, m
727:                                .getParameterTypes()));
728:                        short data[] = { CONSTANT_METHOD, ci, nt };
729:                        x = data;
730:                    } else if (x instanceof  Method) {
731:                        Method m = (Method) x;
732:                        Class c = m.getDeclaringClass();
733:                        short kind = c.isInterface() ? CONSTANT_INTERFACEMETHOD
734:                                : CONSTANT_METHOD;
735:                        short ci = getIndex(c);
736:                        short nt = getNTIndex(m.getName(), getSig(m
737:                                .getReturnType(), m.getParameterTypes()));
738:                        short data[] = { kind, ci, nt };
739:                        x = data;
740:                    } else if (x instanceof  ProxyAssembler) {
741:                        ProxyAssembler asm = (ProxyAssembler) x;
742:                        short ci = getUtfIndex(asm.className.replace('.', '/'));
743:                        short data[] = { CONSTANT_CLASS, ci };
744:                        x = data;
745:                    } else if (x instanceof  AMember) {
746:                        AMember m = (AMember) x;
747:                        short kind = !isMethodSig(m.sig) ? CONSTANT_FIELD
748:                                : m.asm.isInterface() ? CONSTANT_INTERFACEMETHOD
749:                                        : CONSTANT_METHOD;
750:                        short ci = getIndex(m.asm);
751:                        short nt = getNTIndex(m.name, m.sig);
752:                        short data[] = { kind, ci, nt };
753:                        x = data;
754:                    } else if (x instanceof  NameAndType) {
755:                        NameAndType nt = (NameAndType) x;
756:                        short data[] = { CONSTANT_NAMEANDTYPE, nt.name, nt.sig };
757:                        x = data;
758:                    }
759:                    cv.setElementAt(x, i); // update
760:                }
761:
762:                ByteArrayOutputStream bytes = new ByteArrayOutputStream(400);
763:                DataOutputStream ds = new DataOutputStream(bytes);
764:                ds.writeInt(JAVA_MAGIC);
765:                ds.writeShort(JAVA_MINOR_VERSION);
766:                ds.writeShort(JAVA_VERSION);
767:                int cvsize = cv.size();
768:                ds.writeShort(cvsize);
769:                for (int i = 0; i < cv.size(); i++) {
770:                    Object x = cv.elementAt(i);
771:                    if (x == null) {
772:                        continue;
773:                    } else if (x instanceof  short[]) {
774:                        short data[] = (short[]) x;
775:                        ds.writeByte(data[0]);
776:                        for (int j = 1; j < data.length; j++) {
777:                            ds.writeShort(data[j]);
778:                        }
779:                    } else if (x instanceof  byte[]) {
780:                        ds.write((byte[]) x);
781:                    } else if (x instanceof  Integer) {
782:                        ds.writeByte(CONSTANT_INTEGER);
783:                        ds.writeInt(((Integer) x).intValue());
784:                        // (do other primitive literal types?)
785:                    } else {
786:                        throw new RuntimeException("unexpected");
787:                    }
788:                }
789:                ds.writeShort(modifiers);
790:                ds.writeShort(getIndex(this ));
791:                ds.writeShort(getIndex(super Class));
792:                ds.writeShort(interfaces.length);
793:                for (int i = 0; i < interfaces.length; i++) {
794:                    ds.writeShort(getIndex(interfaces[i]));
795:                }
796:                for (int pass = 0; pass <= 1; pass++) {
797:                    boolean methods = (pass > 0);
798:                    ds.writeShort(methods ? nmethods : nfields);
799:                    for (int i = 0; i < members.size(); i++) {
800:                        AMember m = (AMember) members.elementAt(i);
801:                        if (m.name.length() == 0
802:                                || isMethodSig(m.sig) != methods) {
803:                            continue;
804:                        }
805:                        ds.writeShort(m.mods);
806:                        ds.writeShort(getUtfIndex(m.name));
807:                        ds.writeShort(getUtfIndex(m.sig));
808:                        writeAttrs(ds, m.attr);
809:                    }
810:                }
811:                AMember m0 = (AMember) members.elementAt(0);
812:                writeAttrs(ds, (Vector) m0.attr);
813:
814:                // sanity check
815:                if (cvsize != cv.size()) {
816:                    throw new RuntimeException("cvsize");
817:                }
818:
819:                return bytes.toByteArray();
820:            }
821:
822:            private byte[] getMethodCode(AMember m, ByteArrayOutputStream code)
823:                    throws IOException {
824:                if (code.size() == 0) {
825:                    if ((current.mods & (Modifier.NATIVE | Modifier.ABSTRACT)) == 0) {
826:                        current.mods |= Modifier.ABSTRACT;
827:                        modifiers |= Modifier.ABSTRACT;
828:                    }
829:                    return null;
830:                }
831:                ByteArrayOutputStream bytes = new ByteArrayOutputStream(code
832:                        .size() + 30);
833:                DataOutputStream ds = new DataOutputStream(bytes);
834:                int slop = 10; // ??
835:                int max_stack = current.locmax + slop;
836:                int max_locals = current.spmax + slop;
837:                ds.writeShort(max_stack);
838:                ds.writeShort(max_locals);
839:                ds.writeInt(code.size());
840:                code.writeTo(ds);
841:                ds.writeShort(0); // exception_table.length
842:
843:                Vector attrs = new Vector();
844:                for (int i = m.attr.size(); --i >= 0;) {
845:                    Attr ma = (Attr) m.attr.elementAt(i);
846:                    if (ma.name.startsWith("Code.")) {
847:                        m.attr.removeElementAt(i);
848:                        ma.name = ma.name.substring("Code.".length());
849:                        attrs.addElement(ma);
850:                        getUtfIndex(ma.name);
851:                    }
852:                }
853:                writeAttrs(ds, attrs);
854:
855:                return bytes.toByteArray();
856:            }
857:
858:            private void writeAttrs(DataOutputStream ds, Vector attrs)
859:                    throws IOException {
860:                ds.writeShort(attrs.size());
861:                for (int i = 0; i < attrs.size(); i++) {
862:                    Attr a = (Attr) attrs.elementAt(i);
863:                    ds.writeShort(getUtfIndex(a.name));
864:                    if (a.data instanceof  byte[]) {
865:                        byte[] xa = (byte[]) a.data;
866:                        ds.writeInt(xa.length);
867:                        ds.write(xa);
868:                    } else {
869:                        throw new RuntimeException("unexpected");
870:                    }
871:                }
872:            }
873:
874:            private static final int JAVA_MAGIC = 0xcafebabe;
875:
876:            private static final short JAVA_VERSION = 45,
877:                    JAVA_MINOR_VERSION = 3;
878:
879:            private static final short CONSTANT_UTF8 = 1, CONSTANT_UNICODE = 2,
880:                    CONSTANT_INTEGER = 3, CONSTANT_FLOAT = 4,
881:                    CONSTANT_LONG = 5, CONSTANT_DOUBLE = 6, CONSTANT_CLASS = 7,
882:                    CONSTANT_STRING = 8, CONSTANT_FIELD = 9,
883:                    CONSTANT_METHOD = 10, CONSTANT_INTERFACEMETHOD = 11,
884:                    CONSTANT_NAMEANDTYPE = 12;
885:
886:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.