public void getArgs(Code code, Class<?>[] parameters) throws Exception { if (parameters.length == 0) { code.getstatic("org/python/core/Py", "EmptyObjects", $pyObjArr); } else { code.iconst(parameters.length); code.anewarray("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; code.invokestatic("org/python/core/Py", "newInteger", "(I)" + $pyInteger); break; case tLong: code.lload(local_index); local_index += 2; code.invokestatic("org/python/core/Py", "newInteger", "(J)" + $pyObj); break; case tFloat: code.fload(local_index); local_index += 1; code.invokestatic("org/python/core/Py", "newFloat", "(F)" + $pyFloat); break; case tDouble: code.dload(local_index); local_index += 2; code.invokestatic("org/python/core/Py", "newFloat", "(D)" + $pyFloat); break; case tCharacter: code.iload(local_index); local_index += 1; code.invokestatic("org/python/core/Py", "newString", "(C)" + $pyStr); break; default: code.aload(local_index); local_index += 1; break; } code.aastore(); } code.aload(array); } }
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 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); } }
public void doJavaCall(Code code, String name, String type, String jcallName) throws Exception { code.invokevirtual("org/python/core/PyObject", jcallName, makeSig($pyObj, $objArr)); code.invokestatic("org/python/core/Py", "py2" + name, makeSig(type, $pyObj)); }