📄 proxymaker.java
字号:
// Copyright (c) Corporation for National Research Initiativespackage org.python.compiler;import java.util.Hashtable;import java.util.Enumeration;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.lang.reflect.Constructor;import java.io.*;import org.python.core.Py;public class ProxyMaker implements ClassConstants{ public static final int tBoolean=0; public static final int tByte=1; public static final int tShort=2; public static final int tInteger=3; public static final int tLong=4; public static final int tFloat=5; public static final int tDouble=6; public static final int tCharacter=7; public static final int tVoid=8; public static final int tOther=9; public static final int tNone=10; public static Hashtable types=fillTypes(); public static Hashtable fillTypes() { Hashtable types = new Hashtable(); types.put(Boolean.TYPE, new Integer(tBoolean)); types.put(Byte.TYPE, new Integer(tByte)); types.put(Short.TYPE, new Integer(tShort)); types.put(Integer.TYPE, new Integer(tInteger)); types.put(Long.TYPE, new Integer(tLong)); types.put(Float.TYPE, new Integer(tFloat)); types.put(Double.TYPE, new Integer(tDouble)); types.put(Character.TYPE, new Integer(tCharacter)); types.put(Void.TYPE, new Integer(tVoid)); return types; } public static int getType(Class c) { if (c == null) return tNone; Object i = types.get(c); if (i == null) return tOther; else return ((Integer)i).intValue(); } Class superclass; Class[] interfaces; Hashtable names; Hashtable supernames = new Hashtable(); public ClassFile classfile; public String myClass; public boolean isAdapter=false; // Ctor used by makeProxy and AdapterMaker. public ProxyMaker(String classname, Class superclass) { this.myClass = "org.python.proxies."+classname; if (superclass.isInterface()) { this.superclass = Object.class; this.interfaces = new Class[] {superclass}; } else { this.superclass = superclass; this.interfaces = new Class[0]; } } // Ctor used by javamaker. public ProxyMaker(String myClass, Class superclass, Class[] interfaces) { this.myClass = myClass; if (superclass == null) superclass = Object.class; this.superclass = superclass; if (interfaces == null) interfaces = new Class[0]; this.interfaces = interfaces; } public static String mapClass(Class c) { String name = c.getName(); int index = name.indexOf("."); if (index == -1) return name; StringBuffer buf = new StringBuffer(name.length()); int last_index = 0; while (index != -1) { buf.append(name.substring(last_index, index)); buf.append("/"); last_index = index+1; index = name.indexOf(".", last_index); } buf.append(name.substring(last_index, name.length())); return buf.toString(); } public static String mapType(Class type) { if (type.isArray()) return "["+mapType(type.getComponentType()); switch (getType(type)) { case tByte: return "B"; case tCharacter: return "C"; case tDouble: return "D"; case tFloat: return "F"; case tInteger: return "I"; case tLong: return "J"; case tShort: return "S"; case tBoolean: return "Z"; case tVoid: return "V"; default: return "L"+mapClass(type)+";"; } } public static String makeSignature(Class[] sig, Class ret) { StringBuffer buf=new StringBuffer(); buf.append("("); for (int i=0; i<sig.length; i++) { buf.append(mapType(sig[i])); } buf.append(")"); buf.append(mapType(ret)); return buf.toString(); } public void doConstants() throws Exception { Code code = classfile.addMethod("<clinit>", "()V", Modifier.STATIC); code.return_(); } public static void doReturn(Code code, Class type) throws Exception { switch (getType(type)) { case tNone: break; case tCharacter: case tBoolean: case tByte: case tShort: case tInteger: code.ireturn(); break; case tLong: code.lreturn(); break; case tFloat: code.freturn(); break; case tDouble: code.dreturn(); break; case tVoid: code.return_(); break; default: code.areturn(); break; } } public static void doNullReturn(Code code, Class type) throws Exception { switch (getType(type)) { case tNone: break; case tCharacter: case tBoolean: case tByte: case tShort: case tInteger: code.iconst(0); code.ireturn(); break; case tLong: code.ldc(code.pool.Long(0)); code.lreturn(); break; case tFloat: code.ldc(code.pool.Float((float)0.)); code.freturn(); break; case tDouble: code.ldc(code.pool.Double(0.)); code.dreturn(); break; case tVoid: code.return_(); break; default: code.aconst_null(); code.areturn(); break; } } public void callSuper(Code code, String name, String superclass, Class[] parameters, Class ret, String sig) throws Exception { code.aload(0); int local_index; int i; for (i=0, local_index=1; i<parameters.length; i++) { switch(getType(parameters[i])) { case tCharacter: case tBoolean: case tByte: case tShort: case tInteger: code.iload(local_index); local_index += 1; break; case tLong: code.lload(local_index); local_index += 2; break; case tFloat: code.fload(local_index); local_index += 1; break; case tDouble: code.dload(local_index); local_index += 2; break; default: code.aload(local_index); local_index += 1; break; } } int meth = code.pool.Methodref(superclass, name, sig); code.invokespecial(meth); doReturn(code, ret); } public void doJavaCall(Code code, String name, String type, String jcallName) throws Exception { int jcall = code.pool.Methodref( "org/python/core/PyObject", jcallName, "(" + $objArr + ")" + $pyObj); int py2j = code.pool.Methodref( "org/python/core/Py", "py2"+name, "(" + $pyObj + ")"+type); code.invokevirtual(jcall); code.invokestatic(py2j); } public void getArgs(Code code, Class[] parameters) throws Exception { if (parameters.length == 0) { int EmptyObjects = code.pool.Fieldref( "org/python/core/Py", "EmptyObjects", $pyObjArr); code.getstatic(EmptyObjects); } else { code.iconst(parameters.length); code.anewarray(code.pool.Class("java/lang/Object")); int array = code.getLocal("[org/python/core/PyObject"); code.astore(array); int local_index; int i; for (i=0, local_index=1; i<parameters.length; i++) { code.aload(array); code.iconst(i); switch (getType(parameters[i])) { case tBoolean: case tByte: case tShort: case tInteger: code.iload(local_index); local_index += 1; int newInteger = code.pool.Methodref( "org/python/core/Py", "newInteger", "(I)" + $pyInteger); code.invokestatic(newInteger); break; case tLong: code.lload(local_index); local_index += 2; int newInteger1 = code.pool.Methodref( "org/python/core/Py", "newInteger", "(J)" + $pyObj); code.invokestatic(newInteger1); break; case tFloat: code.fload(local_index); local_index += 1; int newFloat = code.pool.Methodref( "org/python/core/Py", "newFloat", "(F)" + $pyFloat); code.invokestatic(newFloat); break; case tDouble: code.dload(local_index); local_index += 2; int newFloat1 = code.pool.Methodref( "org/python/core/Py", "newFloat", "(D)" + $pyFloat); code.invokestatic(newFloat1); break; case tCharacter: code.iload(local_index); local_index += 1; int newString = code.pool.Methodref( "org/python/core/Py", "newString", "(C)" + $pyStr); code.invokestatic(newString); break; default: code.aload(local_index); local_index += 1; break; } code.aastore(); } code.aload(array); } } public void callMethod(Code code, String name, Class[] parameters, Class ret, Class[] exceptions) throws Exception { Label start = null; Label end = null; String jcallName = "_jcall"; int instLocal = 0; if (exceptions.length > 0) { start = code.getLabel(); end = code.getLabel(); jcallName = "_jcallexc"; instLocal = code.getLocal("org/python/core/PyObject"); code.astore(instLocal); start.setPosition(); code.aload(instLocal); } getArgs(code, parameters); switch (getType(ret)) { case tCharacter: doJavaCall(code, "char", "C", jcallName); break; case tBoolean: doJavaCall(code, "boolean", "Z", jcallName); break; case tByte: case tShort: case tInteger: doJavaCall(code, "int", "I", jcallName); break; case tLong: doJavaCall(code, "long", "J", jcallName); break; case tFloat: doJavaCall(code, "float", "F", jcallName); break; case tDouble: doJavaCall(code, "double", "D", jcallName); break; case tVoid: doJavaCall(code, "void", "V", jcallName); break; default: int jcall = code.pool.Methodref( "org/python/core/PyObject", jcallName, "(" + $objArr + ")" + $pyObj); code.invokevirtual(jcall); /* catching exceptions is not vm mandatory Label forname_start =code.getLabel(); Label forname_end = code.getLabel(); Label forname_exch_start = code.getLabel(); Label forname_exch_end = code.getLabel(); forname_start.setPosition(); */ int forname = code.pool.Methodref( "java/lang/Class","forName", "(" + $str + ")" + $clss); code.ldc(ret.getName()); code.invokestatic(forname); /* forname_end.setPosition(); code.goto_(forname_exch_end); forname_exch_start.setPosition(); code.stack = 1; // never reached, but this code keeps the verifier happy code.pop(); code.aconst_null(); code.dup(); forname_exch_end.setPosition(); code.addExceptionHandler(forname_start,forname_end, forname_exch_start,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -