001: // Copyright (c) Corporation for National Research Initiatives
002:
003: package org.python.compiler;
004:
005: import java.lang.reflect.Method;
006: import java.lang.reflect.Modifier;
007:
008: import org.python.core.PyObject;
009:
010: public class JavaMaker extends ProxyMaker implements ClassConstants {
011: public String pythonClass, pythonModule;
012: public String[] properties;
013: public String[] packages;
014: //Hashtable methods;
015: PyObject methods;
016: public boolean frozen, main;
017:
018: public JavaMaker(Class super class, Class[] interfaces,
019: String pythonClass, String pythonModule, String myClass,
020: PyObject methods) {
021: this (super class, interfaces, pythonClass, pythonModule,
022: myClass, null, null, methods, false, false);
023: }
024:
025: public JavaMaker(Class super class, Class[] interfaces,
026: String pythonClass, String pythonModule, String myClass,
027: String[] packages, String[] properties, PyObject methods,
028: boolean frozen, boolean main) {
029: super (myClass, super class, interfaces);
030: // System.out.println("props: "+properties+", "+properties.length);
031: this .pythonClass = pythonClass;
032: this .pythonModule = pythonModule;
033: this .packages = packages;
034: this .properties = properties;
035: this .frozen = frozen;
036: this .main = main;
037: this .methods = methods;
038: }
039:
040: private void makeStrings(Code code, String[] list) throws Exception {
041: if (list != null) {
042: int n = list.length;
043: code.iconst(n);
044: code.anewarray(code.pool.Class("java/lang/String"));
045: int strings = code.getLocal("[java/lang/String");
046: code.astore(strings);
047: for (int i = 0; i < n; i++) {
048: code.aload(strings);
049: code.iconst(i);
050: code.ldc(list[i]);
051: code.aastore();
052: }
053: code.aload(strings);
054: code.freeLocal(strings);
055: } else {
056: code.aconst_null();
057: }
058: }
059:
060: public void addConstructor(String name, Class[] parameters,
061: Class ret, String sig, int access) throws Exception {
062: /* Need a fancy constructor for the Java side of things */
063: Code code = classfile.addMethod("<init>", sig, access);
064: callSuper(code, "<init>", name, parameters, null, sig);
065: code.aload(0);
066: getArgs(code, parameters);
067:
068: int initProxy = code.pool.Methodref(classfile.name,
069: "__initProxy__", "([Ljava/lang/Object;)V");
070: code.invokevirtual(initProxy);
071: code.return_();
072: }
073:
074: public void addProxy() throws Exception {
075: if (methods != null)
076: super .addProxy();
077:
078: // _initProxy method
079: Code code = classfile.addMethod("__initProxy__",
080: "([Ljava/lang/Object;)V", Modifier.PUBLIC);
081:
082: code.aload(0);
083: code.ldc(pythonModule);
084: code.ldc(pythonClass);
085:
086: code.aload(1);
087:
088: makeStrings(code, packages);
089: makeStrings(code, properties);
090:
091: code.iconst(frozen ? 1 : 0);
092:
093: int initProxy = code.pool.Methodref("org/python/core/Py",
094: "initProxy", "(" + $pyProxy + $str + $str + $objArr
095: + $strArr + $strArr + "Z)V");
096: code.invokestatic(initProxy);
097: code.return_();
098:
099: if (main)
100: addMain();
101: }
102:
103: // public void addMethods(Class c) throws Exception {
104: // if (methods != null) {
105: // super.addMethods(c);
106: // }
107: // }
108:
109: public void addMethod(Method method, int access) throws Exception {
110: //System.out.println("add: "+method.getName()+", "+
111: // methods.containsKey(method.getName()));
112: // Check to see if it's an abstract method
113: if (Modifier.isAbstract(access)) {
114: // Maybe throw an exception here???
115: super .addMethod(method, access);
116: } else if (methods.__finditem__(method.getName().intern()) != null) {
117: super .addMethod(method, access);
118: } else if (Modifier.isProtected(method.getModifiers())) {
119: addSuperMethod(method, access);
120: }
121: }
122:
123: /*
124: public void addSuperMethod(String methodName, String superName,
125: String superclass, Class[] parameters,
126: Class ret, String sig, int access)
127: throws Exception
128: {
129: if (!PyProxy.class.isAssignableFrom(this.superclass)) {
130: super.addSuperMethod(methodName,superName,superclass,parameters,
131: ret,sig,access);
132: }
133: }
134:
135: */
136:
137: public void addMain() throws Exception {
138: Code code = classfile.addMethod("main", "(" + $str + ")V",
139: ClassFile.PUBLIC | ClassFile.STATIC);
140:
141: // Load the class of the Python module to run
142: int forname = code.pool.Methodref("java/lang/Class", "forName",
143: "(" + $str + ")" + $clss);
144: code.ldc(pythonModule);
145: code.invokestatic(forname);
146:
147: // Load in any command line arguments
148: code.aload(0);
149: makeStrings(code, packages);
150: makeStrings(code, properties);
151: code.iconst(frozen ? 1 : 0);
152:
153: int runMain = code.pool.Methodref("org/python/core/Py",
154: "runMain", "(" + $clss + $strArr + $strArr + $strArr
155: + "Z)V");
156: code.invokestatic(runMain);
157: code.return_();
158: }
159: }
|