KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > compiler > ProxyMaker


1 // Copyright (c) Corporation for National Research Initiatives
2
package org.python.compiler;
3
4 import java.util.Hashtable JavaDoc;
5 import java.util.Enumeration JavaDoc;
6 import java.lang.reflect.Method JavaDoc;
7 import java.lang.reflect.Modifier JavaDoc;
8 import java.lang.reflect.Constructor JavaDoc;
9 import java.io.*;
10 import org.python.core.Py;
11
12 public class ProxyMaker implements ClassConstants
13 {
14     public static final int tBoolean=0;
15     public static final int tByte=1;
16     public static final int tShort=2;
17     public static final int tInteger=3;
18     public static final int tLong=4;
19     public static final int tFloat=5;
20     public static final int tDouble=6;
21     public static final int tCharacter=7;
22     public static final int tVoid=8;
23     public static final int tOther=9;
24     public static final int tNone=10;
25
26     public static Hashtable JavaDoc types=fillTypes();
27
28     public static Hashtable JavaDoc fillTypes() {
29         Hashtable JavaDoc types = new Hashtable JavaDoc();
30         types.put(Boolean.TYPE, new Integer JavaDoc(tBoolean));
31         types.put(Byte.TYPE, new Integer JavaDoc(tByte));
32         types.put(Short.TYPE, new Integer JavaDoc(tShort));
33         types.put(Integer.TYPE, new Integer JavaDoc(tInteger));
34         types.put(Long.TYPE, new Integer JavaDoc(tLong));
35         types.put(Float.TYPE, new Integer JavaDoc(tFloat));
36         types.put(Double.TYPE, new Integer JavaDoc(tDouble));
37         types.put(Character.TYPE, new Integer JavaDoc(tCharacter));
38         types.put(Void.TYPE, new Integer JavaDoc(tVoid));
39         return types;
40     }
41
42     public static int getType(Class JavaDoc c) {
43         if (c == null) return tNone;
44         Object JavaDoc i = types.get(c);
45         if (i == null) return tOther;
46         else return ((Integer JavaDoc)i).intValue();
47     }
48
49     Class JavaDoc superclass;
50     Class JavaDoc[] interfaces;
51     Hashtable JavaDoc names;
52     Hashtable JavaDoc supernames = new Hashtable JavaDoc();
53     public ClassFile classfile;
54     public String JavaDoc myClass;
55     public boolean isAdapter=false;
56
57     // Ctor used by makeProxy and AdapterMaker.
58
public ProxyMaker(String JavaDoc classname, Class JavaDoc superclass) {
59         this.myClass = "org.python.proxies."+classname;
60         if (superclass.isInterface()) {
61             this.superclass = Object JavaDoc.class;
62             this.interfaces = new Class JavaDoc[] {superclass};
63         } else {
64             this.superclass = superclass;
65             this.interfaces = new Class JavaDoc[0];
66         }
67     }
68
69     // Ctor used by javamaker.
70
public ProxyMaker(String JavaDoc myClass, Class JavaDoc superclass, Class JavaDoc[] interfaces) {
71         this.myClass = myClass;
72         if (superclass == null)
73             superclass = Object JavaDoc.class;
74         this.superclass = superclass;
75         if (interfaces == null)
76             interfaces = new Class JavaDoc[0];
77         this.interfaces = interfaces;
78     }
79
80     public static String JavaDoc mapClass(Class JavaDoc c) {
81         String JavaDoc name = c.getName();
82         int index = name.indexOf(".");
83         if (index == -1)
84             return name;
85
86         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(name.length());
87         int last_index = 0;
88         while (index != -1) {
89             buf.append(name.substring(last_index, index));
90             buf.append("/");
91             last_index = index+1;
92             index = name.indexOf(".", last_index);
93         }
94         buf.append(name.substring(last_index, name.length()));
95         return buf.toString();
96     }
97
98     public static String JavaDoc mapType(Class JavaDoc type) {
99         if (type.isArray())
100             return "["+mapType(type.getComponentType());
101
102         switch (getType(type)) {
103         case tByte: return "B";
104         case tCharacter: return "C";
105         case tDouble: return "D";
106         case tFloat: return "F";
107         case tInteger: return "I";
108         case tLong: return "J";
109         case tShort: return "S";
110         case tBoolean: return "Z";
111         case tVoid: return "V";
112         default:
113             return "L"+mapClass(type)+";";
114         }
115     }
116
117     public static String JavaDoc makeSignature(Class JavaDoc[] sig, Class JavaDoc ret) {
118         StringBuffer JavaDoc buf=new StringBuffer JavaDoc();
119         buf.append("(");
120         for (int i=0; i<sig.length; i++) {
121             buf.append(mapType(sig[i]));
122         }
123         buf.append(")");
124         buf.append(mapType(ret));
125         return buf.toString();
126     }
127
128
129     public void doConstants() throws Exception JavaDoc {
130         Code code = classfile.addMethod("<clinit>", "()V", Modifier.STATIC);
131         code.return_();
132     }
133
134     public static void doReturn(Code code, Class JavaDoc type) throws Exception JavaDoc {
135         switch (getType(type)) {
136         case tNone:
137             break;
138         case tCharacter:
139         case tBoolean:
140         case tByte:
141         case tShort:
142         case tInteger:
143             code.ireturn();
144             break;
145         case tLong:
146             code.lreturn();
147             break;
148         case tFloat:
149             code.freturn();
150             break;
151         case tDouble:
152             code.dreturn();
153             break;
154         case tVoid:
155             code.return_();
156             break;
157         default:
158             code.areturn();
159             break;
160         }
161     }
162
163     public static void doNullReturn(Code code, Class JavaDoc type) throws Exception JavaDoc {
164         switch (getType(type)) {
165         case tNone:
166             break;
167         case tCharacter:
168         case tBoolean:
169         case tByte:
170         case tShort:
171         case tInteger:
172             code.iconst(0);
173             code.ireturn();
174             break;
175         case tLong:
176             code.ldc(code.pool.Long(0));
177             code.lreturn();
178             break;
179         case tFloat:
180             code.ldc(code.pool.Float((float)0.));
181             code.freturn();
182             break;
183         case tDouble:
184             code.ldc(code.pool.Double(0.));
185             code.dreturn();
186             break;
187         case tVoid:
188             code.return_();
189             break;
190         default:
191             code.aconst_null();
192             code.areturn();
193             break;
194         }
195     }
196
197     public void callSuper(Code code, String JavaDoc name, String JavaDoc superclass,
198                           Class JavaDoc[] parameters, Class JavaDoc ret,
199                           String JavaDoc sig)
200         throws Exception JavaDoc
201     {
202         code.aload(0);
203         int local_index;
204         int i;
205         for (i=0, local_index=1; i<parameters.length; i++) {
206             switch(getType(parameters[i])) {
207             case tCharacter:
208             case tBoolean:
209             case tByte:
210             case tShort:
211             case tInteger:
212                 code.iload(local_index);
213                 local_index += 1;
214                 break;
215             case tLong:
216                 code.lload(local_index);
217                 local_index += 2;
218                 break;
219             case tFloat:
220                 code.fload(local_index);
221                 local_index += 1;
222                 break;
223             case tDouble:
224                 code.dload(local_index);
225                 local_index += 2;
226                 break;
227             default:
228                 code.aload(local_index);
229                 local_index += 1;
230                 break;
231             }
232         }
233         int meth = code.pool.Methodref(superclass, name, sig);
234         code.invokespecial(meth);
235         doReturn(code, ret);
236     }
237
238     public void doJavaCall(Code code, String JavaDoc name, String JavaDoc type,
239                           String JavaDoc jcallName)
240         throws Exception JavaDoc
241     {
242         int jcall = code.pool.Methodref(
243             "org/python/core/PyObject", jcallName,
244             "(" + $objArr + ")" + $pyObj);
245
246         int py2j = code.pool.Methodref(
247             "org/python/core/Py", "py2"+name,
248             "(" + $pyObj + ")"+type);
249
250         code.invokevirtual(jcall);
251         code.invokestatic(py2j);
252     }
253
254
255     public void getArgs(Code code, Class JavaDoc[] parameters) throws Exception JavaDoc {
256         if (parameters.length == 0) {
257             int EmptyObjects = code.pool.Fieldref(
258                 "org/python/core/Py", "EmptyObjects", $pyObjArr);
259             code.getstatic(EmptyObjects);
260         }
261         else {
262             code.iconst(parameters.length);
263             code.anewarray(code.pool.Class("java/lang/Object"));
264             int array = code.getLocal("[org/python/core/PyObject");
265             code.astore(array);
266
267             int local_index;
268             int i;
269             for (i=0, local_index=1; i<parameters.length; i++) {
270                 code.aload(array);
271                 code.iconst(i);
272
273                 switch (getType(parameters[i])) {
274                 case tBoolean:
275                 case tByte:
276                 case tShort:
277                 case tInteger:
278                     code.iload(local_index);
279                     local_index += 1;
280
281                     int newInteger = code.pool.Methodref(
282                         "org/python/core/Py",
283                         "newInteger", "(I)" + $pyInteger);
284                     code.invokestatic(newInteger);
285                     break;
286                 case tLong:
287                     code.lload(local_index);
288                     local_index += 2;
289
290                     int newInteger1 = code.pool.Methodref(
291                         "org/python/core/Py",
292                         "newInteger", "(J)" + $pyObj);
293                     code.invokestatic(newInteger1);
294                     break;
295                 case tFloat:
296                     code.fload(local_index);
297                     local_index += 1;
298
299                     int newFloat = code.pool.Methodref(
300                         "org/python/core/Py",
301                         "newFloat", "(F)" + $pyFloat);
302                     code.invokestatic(newFloat);
303                     break;
304                 case tDouble:
305                     code.dload(local_index);
306                     local_index += 2;
307
308                     int newFloat1 = code.pool.Methodref(
309                         "org/python/core/Py",
310                         "newFloat", "(D)" + $pyFloat);
311                     code.invokestatic(newFloat1);
312                     break;
313                 case tCharacter:
314                     code.iload(local_index);
315                     local_index += 1;
316                     int newString = code.pool.Methodref(
317                         "org/python/core/Py",
318                         "newString", "(C)" + $pyStr);
319                     code.invokestatic(newString);
320                     break;
321                 default:
322                     code.aload(local_index);
323                     local_index += 1;
324                     break;
325                 }
326                 code.aastore();
327             }
328             code.aload(array);
329         }
330     }
331
332     public void callMethod(Code code, String JavaDoc name, Class JavaDoc[] parameters,
333                            Class JavaDoc ret, Class JavaDoc[] exceptions)
334         throws Exception JavaDoc
335     {
336         Label start = null;
337         Label end = null;
338
339         String JavaDoc jcallName = "_jcall";
340         int instLocal = 0;
341
342         if (exceptions.length > 0) {
343             start = code.getLabel();
344             end = code.getLabel();
345             jcallName = "_jcallexc";
346             instLocal = code.getLocal("org/python/core/PyObject");
347             code.astore(instLocal);
348             start.setPosition();
349             code.aload(instLocal);
350         }
351
352         getArgs(code, parameters);
353
354         switch (getType(ret)) {
355         case tCharacter:
356             doJavaCall(code, "char", "C", jcallName);
357             break;
358         case tBoolean:
359             doJavaCall(code, "boolean", "Z", jcallName);
360             break;
361         case tByte:
362         case tShort:
363         case tInteger:
364             doJavaCall(code, "int", "I", jcallName);
365             break;
366         case tLong:
367             doJavaCall(code, "long", "J", jcallName);
368             break;
369         case tFloat:
370             doJavaCall(code, "float", "F", jcallName);
371             break;
372         case tDouble:
373             doJavaCall(code, "double", "D", jcallName);
374             break;
375         case tVoid:
376             doJavaCall(code, "void", "V", jcallName);
377             break;
378         default:
379             int jcall = code.pool.Methodref(
380                 "org/python/core/PyObject", jcallName,
381                 "(" + $objArr + ")" + $pyObj);
382             code.invokevirtual(jcall);
383             /* catching exceptions is not vm mandatory
384             Label forname_start =code.getLabel();
385             Label forname_end = code.getLabel();
386             Label forname_exch_start = code.getLabel();
387             Label forname_exch_end = code.getLabel();
388             forname_start.setPosition();
389             */

390             int forname = code.pool.Methodref(
391                 "java/lang/Class","forName",
392                 "(" + $str + ")" + $clss);
393             code.ldc(ret.getName());
394             code.invokestatic(forname);
395             /*
396             forname_end.setPosition();
397             code.goto_(forname_exch_end);
398             forname_exch_start.setPosition();
399             code.stack = 1;
400             // never reached, but this code keeps the verifier happy
401             code.pop();
402             code.aconst_null();
403             code.dup();
404             forname_exch_end.setPosition();
405
406             code.addExceptionHandler(forname_start,forname_end,
407                     forname_exch_start,
408                     code.pool.Class("java/lang/ClassNotFoundException"));
409             */

410             int tojava = code.pool.Methodref(
411                 "org/python/core/Py", "tojava",
412                 "(" + $pyObj + $clss + ")" + $obj);
413             code.invokestatic(tojava);
414             // I guess I need this checkcast to keep the verifier happy
415
code.checkcast(code.pool.Class(mapClass(ret)));
416             break;
417         }
418         if (exceptions.length > 0)
419             end.setPosition();
420
421         doReturn(code, ret);
422
423         if (exceptions.length > 0) {
424             boolean throwableFound = false;
425
426             Label handlerStart = null;
427             for (int i = 0; i < exceptions.length; i++) {
428                 handlerStart = code.getLabel();
429                 handlerStart.setPosition();
430                 code.stack = 1;
431                 int excLocal = code.getLocal("java/lang/Throwable");
432                 code.astore(excLocal);
433
434                 code.aload(excLocal);
435                 code.athrow();
436
437                 code.addExceptionHandler(start, end, handlerStart,
438                                  code.pool.Class(mapClass(exceptions[i])));
439                 doNullReturn(code, ret);
440
441                 code.freeLocal(excLocal);
442                 if (exceptions[i] == Throwable JavaDoc.class)
443                     throwableFound = true;
444             }
445
446             if (!throwableFound) {
447                 // The final catch (Throwable)
448
handlerStart = code.getLabel();
449                 handlerStart.setPosition();
450                 code.stack = 1;
451                 int excLocal = code.getLocal("java/lang/Throwable");
452                 code.astore(excLocal);
453                 code.aload(instLocal);
454                 code.aload(excLocal);
455
456                 int jthrow = code.pool.Methodref(
457                     "org/python/core/PyObject", "_jthrow",
458                     "(" + $throwable + ")V");
459                 code.invokevirtual(jthrow);
460
461                 code.addExceptionHandler(start, end, handlerStart,
462                                      code.pool.Class("java/lang/Throwable"));
463                 code.freeLocal(excLocal);
464                 doNullReturn(code, ret);
465             }
466             code.freeLocal(instLocal);
467         }
468     }
469
470
471     public void addMethod(Method JavaDoc method, int access) throws Exception JavaDoc {
472         boolean isAbstract = false;
473
474         if (Modifier.isAbstract(access)) {
475             access = access & ~Modifier.ABSTRACT;
476             isAbstract = true;
477         }
478
479         Class JavaDoc[] parameters = method.getParameterTypes();
480         Class JavaDoc ret = method.getReturnType();
481         String JavaDoc sig = makeSignature(parameters, ret);
482
483         String JavaDoc name = method.getName();
484 // System.out.println(name+": "+sig);
485
names.put(name, name);
486
487         Code code = classfile.addMethod(name, sig, access);
488
489         code.aload(0);
490         code.ldc(name);
491
492         if (!isAbstract) {
493             int tmp = code.getLocal("org/python/core/PyObject");
494             int jfindattr = code.pool.Methodref(
495                 "org/python/core/Py",
496                 "jfindattr",
497                 "(" + $pyProxy + $str + ")" + $pyObj);
498             code.invokestatic(jfindattr);
499
500             code.astore(tmp);
501             code.aload(tmp);
502
503             Label callPython = code.getLabel();
504
505             code.ifnonnull(callPython);
506
507             String JavaDoc superclass = mapClass(method.getDeclaringClass());
508
509             callSuper(code, name, superclass, parameters, ret, sig);
510             callPython.setPosition();
511             code.aload(tmp);
512             callMethod(code, name, parameters, ret,
513                        method.getExceptionTypes());
514
515             addSuperMethod("super__"+name, name, superclass, parameters,
516                            ret, sig, access);
517         }
518         else {
519             if (!isAdapter) {
520                 int jgetattr = code.pool.Methodref(
521                     "org/python/core/Py",
522                     "jgetattr",
523                     "(" + $pyProxy + $str + ")" + $pyObj);
524                 code.invokestatic(jgetattr);
525                 callMethod(code, name, parameters, ret,
526                            method.getExceptionTypes());
527             }
528             else {
529                 int jfindattr = code.pool.Methodref(
530                     "org/python/core/Py",
531                     "jfindattr",
532                     "(" + $pyProxy + $str + ")" + $pyObj);
533                 code.invokestatic(jfindattr);
534                 code.dup();
535                 Label returnNull = code.getLabel();
536                 code.ifnull(returnNull);
537                 callMethod(code, name, parameters, ret,
538                            method.getExceptionTypes());
539                 returnNull.setPosition();
540                 code.pop();
541                 doNullReturn(code, ret);
542             }
543         }
544     }
545
546     private String JavaDoc methodString(Method JavaDoc m) {
547         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(m.getName());
548         buf.append(":");
549         Class JavaDoc[] params = m.getParameterTypes();
550         for (int i=0; i<params.length; i++) {
551             buf.append(params[i].getName());
552             buf.append(",");
553         }
554         return buf.toString();
555     }
556
557     protected void addMethods(Class JavaDoc c, Hashtable JavaDoc t) throws Exception JavaDoc {
558         Method JavaDoc[] methods = c.getDeclaredMethods();
559         for (int i=0; i<methods.length; i++) {
560             Method JavaDoc method = methods[i];
561             String JavaDoc s = methodString(method);
562             if (t.containsKey(s))
563                 continue;
564             t.put(s, s);
565
566             int access = method.getModifiers();
567             if (Modifier.isStatic(access) || Modifier.isPrivate(access)) {
568                 continue;
569             }
570
571             if (Modifier.isNative(access)) {
572                 access = access & ~Modifier.NATIVE;
573             }
574
575             if (Modifier.isProtected(access)) {
576                 access = (access & ~Modifier.PROTECTED) | Modifier.PUBLIC;
577                 if (Modifier.isFinal(access)) {
578                     addSuperMethod(methods[i], access);
579                     continue;
580                 }
581             }
582             else if (Modifier.isFinal(access)) {
583                 continue;
584             }
585             addMethod(methods[i], access);
586         }
587
588         Class JavaDoc sc = c.getSuperclass();
589         if (sc != null)
590             addMethods(sc, t);
591
592         Class JavaDoc[] interfaces = c.getInterfaces();
593         for (int j=0; j<interfaces.length; j++) {
594             addMethods(interfaces[j], t);
595         }
596     }
597
598     public void addConstructor(String JavaDoc name, Class JavaDoc[] parameters, Class JavaDoc ret,
599                                String JavaDoc sig, int access)
600         throws Exception JavaDoc
601     {
602         Code code = classfile.addMethod("<init>", sig, access);
603         callSuper(code, "<init>", name, parameters, Void.TYPE, sig);
604     }
605
606     public void addConstructors(Class JavaDoc c) throws Exception JavaDoc {
607         Constructor JavaDoc[] constructors = c.getDeclaredConstructors();
608         String JavaDoc name = mapClass(c);
609         for (int i=0; i<constructors.length; i++) {
610             int access = constructors[i].getModifiers();
611             if (Modifier.isPrivate(access))
612                 continue;
613             if (Modifier.isNative(access))
614                 access = access & ~Modifier.NATIVE;
615             if (Modifier.isProtected(access))
616                 access = access & ~Modifier.PROTECTED | Modifier.PUBLIC;
617             Class JavaDoc[] parameters = constructors[i].getParameterTypes();
618             String JavaDoc sig = makeSignature(parameters, Void.TYPE);
619             addConstructor(name, parameters, Void.TYPE, sig, access);
620         }
621     }
622
623     // Super methods are added for the following three reasons:
624
//
625
// 1) for a protected non-final method add a public method with no
626
// super__ prefix. This gives needed access to this method for
627
// subclasses
628
//
629
// 2) for protected final methods, add a public method with the
630
// super__ prefix. This avoids the danger of trying to override a
631
// final method
632
//
633
// 3) For any other method that is overriden, add a method with the
634
// super__ prefix. This gives access to super. version or the
635
// method.
636
//
637
public void addSuperMethod(Method JavaDoc method, int access) throws Exception JavaDoc {
638         Class JavaDoc[] parameters = method.getParameterTypes();
639         Class JavaDoc ret = method.getReturnType();
640         String JavaDoc sig = makeSignature(parameters, ret);
641         String JavaDoc superclass = mapClass(method.getDeclaringClass());
642         String JavaDoc superName = method.getName();
643         String JavaDoc methodName = superName;
644         if (Modifier.isFinal(access)) {
645             methodName = "super__"+superName;
646             access &= ~Modifier.FINAL;
647         }
648         addSuperMethod(methodName, superName, superclass, parameters,
649                        ret, sig, access);
650     }
651
652     public void addSuperMethod(String JavaDoc methodName, String JavaDoc superName,
653                                String JavaDoc declClass, Class JavaDoc[] parameters,
654                                Class JavaDoc ret, String JavaDoc sig, int access)
655         throws Exception JavaDoc
656     {
657         if (methodName.startsWith("super__")) {
658             /* rationale: JC java-class, P proxy-class subclassing JC
659                in order to avoid infinite recursion P should define super__foo
660                only if no class between P and JC in the hierarchy defines
661                it yet; this means that the python class needing P is the
662                first that redefines the JC method foo.
663             */

664             try {
665                 superclass.getMethod(methodName,parameters);
666                 return;
667             } catch(NoSuchMethodException JavaDoc e) {
668             } catch(SecurityException JavaDoc e) {
669                 return;
670             }
671         }
672         supernames.put(methodName, methodName);
673         Code code = classfile.addMethod(methodName, sig, access);
674         callSuper(code, superName, declClass, parameters, ret, sig);
675     }
676
677     public void addProxy() throws Exception JavaDoc {
678         // implement PyProxy interface
679
classfile.addField("__proxy", "Lorg/python/core/PyInstance;",
680                            Modifier.PROTECTED);
681         // setProxy method
682
Code code = classfile.addMethod("_setPyInstance",
683                                         "(Lorg/python/core/PyInstance;)V",
684                                         Modifier.PUBLIC);
685
686         int field = code.pool.Fieldref(classfile.name, "__proxy",
687                                        "Lorg/python/core/PyInstance;");
688         code.aload(0);
689         code.aload(1);
690         code.putfield(field);
691         code.return_();
692
693         // getProxy method
694
code = classfile.addMethod("_getPyInstance",
695                                    "()Lorg/python/core/PyInstance;",
696                                    Modifier.PUBLIC);
697         code.aload(0);
698         code.getfield(field);
699         code.areturn();
700
701         // implement PyProxy interface
702
classfile.addField("__systemState",
703                            "Lorg/python/core/PySystemState;",
704                            Modifier.PROTECTED | Modifier.TRANSIENT);
705
706         // setProxy method
707
code = classfile.addMethod("_setPySystemState",
708                                    "(Lorg/python/core/PySystemState;)V",
709                                    Modifier.PUBLIC);
710
711         field = code.pool.Fieldref(classfile.name, "__systemState",
712                                    "Lorg/python/core/PySystemState;");
713         code.aload(0);
714         code.aload(1);
715         code.putfield(field);
716         code.return_();
717
718         // getProxy method
719
code = classfile.addMethod("_getPySystemState",
720                                    "()Lorg/python/core/PySystemState;",
721                                    Modifier.PUBLIC);
722         code.aload(0);
723         code.getfield(field);
724         code.areturn();
725     }
726
727     public void addClassDictInit() throws Exception JavaDoc {
728         int n = supernames.size();
729
730         // classDictInit method
731
classfile.addInterface(mapClass(org.python.core.ClassDictInit.class));
732         Code code = classfile.addMethod("classDictInit",
733                                    "(" + $pyObj + ")V",
734                                    Modifier.PUBLIC | Modifier.STATIC);
735         code.aload(0);
736         code.ldc("__supernames__");
737
738         String JavaDoc[] names = new String JavaDoc[n];
739         Enumeration JavaDoc e = supernames.keys();
740         for (int i = 0; e.hasMoreElements(); )
741            names[i++] = (String JavaDoc) e.nextElement();
742         CodeCompiler.makeStrings(code, names, n);
743         int j2py = code.pool.Methodref(
744                       "org/python/core/Py", "java2py",
745                       "(" + $obj + ")" + $pyObj);
746         code.invokestatic(j2py);
747
748         int setitem = code.pool.Methodref(
749                       "org/python/core/PyObject", "__setitem__",
750                       "(" + $str + $pyObj + ")V");
751         code.invokevirtual(setitem);
752         code.return_();
753
754     }
755
756     public void build() throws Exception JavaDoc {
757         names = new Hashtable JavaDoc();
758         int access = superclass.getModifiers();
759         if ((access & Modifier.FINAL) != 0) {
760             throw new InstantiationException JavaDoc("can't subclass final class");
761         }
762         access = Modifier.PUBLIC | Modifier.SYNCHRONIZED;
763
764         classfile = new ClassFile(myClass, mapClass(superclass), access);
765         addProxy();
766         addConstructors(superclass);
767         classfile.addInterface("org/python/core/PyProxy");
768
769         Hashtable JavaDoc seenmethods = new Hashtable JavaDoc();
770         for (int i=0; i<interfaces.length; i++) {
771             if (interfaces[i].isAssignableFrom(superclass)) {
772                 Py.writeWarning("compiler",
773                                 "discarding redundant interface: "+
774                                 interfaces[i].getName());
775                 continue;
776             }
777             classfile.addInterface(mapClass(interfaces[i]));
778             addMethods(interfaces[i], seenmethods);
779         }
780         addMethods(superclass, seenmethods);
781         doConstants();
782         addClassDictInit();
783     }
784
785     public static String JavaDoc makeProxy(Class JavaDoc superclass, OutputStream ostream)
786         throws Exception JavaDoc
787     {
788         ProxyMaker pm = new ProxyMaker(superclass.getName(), superclass);
789         pm.build();
790         pm.classfile.write(ostream);
791         return pm.myClass;
792     }
793
794     public static File makeFilename(String JavaDoc name, File dir) {
795         int index = name.indexOf(".");
796         if (index == -1)
797             return new File(dir, name+".class");
798
799         return makeFilename(name.substring(index+1, name.length()),
800                             new File(dir, name.substring(0, index)));
801     }
802
803     // This is not general enough
804
public static OutputStream getFile(String JavaDoc d, String JavaDoc name)
805         throws IOException
806     {
807         File dir = new File(d);
808         File file = makeFilename(name, dir);
809         new File(file.getParent()).mkdirs();
810         //System.out.println("proxy file: "+file);
811
return new FileOutputStream(file);
812     }
813 }
814
Popular Tags