public void addMethod(Method method, int access) throws Exception { boolean isAbstract = false; if (Modifier.isAbstract(access)) { access = access & ~Modifier.ABSTRACT; isAbstract = true; } Class<?>[] parameters = method.getParameterTypes(); Class<?> ret = method.getReturnType(); String sig = makeSig(ret, parameters); String name = method.getName(); names.add(name); Code code = classfile.addMethod(name, sig, access); code.aload(0); code.ldc(name); if (!isAbstract) { int tmp = code.getLocal("org/python/core/PyObject"); code.invokestatic( "org/python/compiler/ProxyMaker", "findPython", makeSig($pyObj, $pyProxy, $str)); code.astore(tmp); code.aload(tmp); Label callPython = new Label(); code.ifnonnull(callPython); String superClass = mapClass(method.getDeclaringClass()); callSuper(code, name, superClass, parameters, ret, sig); code.label(callPython); code.aload(tmp); callMethod(code, name, parameters, ret, method.getExceptionTypes()); addSuperMethod("super__" + name, name, superClass, parameters, ret, sig, access); } else { code.invokestatic( "org/python/compiler/ProxyMaker", "findPython", makeSig($pyObj, $pyProxy, $str)); code.dup(); Label returnNull = new Label(); code.ifnull(returnNull); callMethod(code, name, parameters, ret, method.getExceptionTypes()); code.label(returnNull); code.pop(); doNullReturn(code, ret); } }
public void addClassDictInit() throws Exception { // classDictInit method classfile.addInterface(mapClass(org.python.core.ClassDictInit.class)); Code code = classfile.addMethod( "classDictInit", makeSig("V", $pyObj), Modifier.PUBLIC | Modifier.STATIC); code.aload(0); code.ldc("__supernames__"); int strArray = CodeCompiler.makeStrings(code, supernames); code.aload(strArray); code.freeLocal(strArray); code.invokestatic("org/python/core/Py", "java2py", makeSig($pyObj, $obj)); code.invokevirtual("org/python/core/PyObject", "__setitem__", makeSig("V", $str, $pyObj)); code.return_(); }
public void iconst(int i) throws IOException { if (i >= -1 && i <= 5) { code.writeByte(3 + i); } else { if (i > -127 && i < 128) { code.writeByte(16); if (i < 0) i = 256 + i; code.writeByte(i); } else { if (i > -32767 && i < 32768) { code.writeByte(17); if (i < 0) i = i + 65536; code.writeShort(i); } else { ldc(pool.Integer(i)); } } } push(1); }
public void ldc(String s) throws IOException { ldc(pool.String(s)); }
public void print(String s) throws IOException { getstatic("java/lang/System", "out", "Ljava/io/PrintStream;"); ldc(s); invokevirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V"); }
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 = new Label(); end = new Label(); jcallName = "_jcallexc"; instLocal = code.getLocal("org/python/core/PyObject"); code.astore(instLocal); code.label(start); 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: code.invokevirtual("org/python/core/PyObject", jcallName, makeSig($pyObj, $objArr)); code.ldc(ret.getName()); code.invokestatic("java/lang/Class", "forName", makeSig($clss, $str)); code.invokestatic("org/python/core/Py", "tojava", makeSig($obj, $pyObj, $clss)); // I guess I need this checkcast to keep the verifier happy code.checkcast(mapClass(ret)); break; } if (end != null) { code.label(end); } doReturn(code, ret); if (exceptions.length > 0) { boolean throwableFound = false; Label handlerStart = null; for (Class<?> exception : exceptions) { handlerStart = new Label(); code.label(handlerStart); int excLocal = code.getLocal("java/lang/Throwable"); code.astore(excLocal); code.aload(excLocal); code.athrow(); code.visitTryCatchBlock(start, end, handlerStart, mapClass(exception)); doNullReturn(code, ret); code.freeLocal(excLocal); if (exception == Throwable.class) throwableFound = true; } if (!throwableFound) { // The final catch (Throwable) handlerStart = new Label(); code.label(handlerStart); int excLocal = code.getLocal("java/lang/Throwable"); code.astore(excLocal); code.aload(instLocal); code.aload(excLocal); code.invokevirtual("org/python/core/PyObject", "_jthrow", makeSig("V", $throwable)); code.visitTryCatchBlock(start, end, handlerStart, "java/lang/Throwable"); code.freeLocal(excLocal); doNullReturn(code, ret); } code.freeLocal(instLocal); } }