Esempio n. 1
0
  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);
    }
  }
Esempio n. 2
0
  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_();
  }
Esempio n. 3
0
 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);
 }
Esempio n. 4
0
 public void ldc(String s) throws IOException {
   ldc(pool.String(s));
 }
Esempio n. 5
0
 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");
 }
Esempio n. 6
0
  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);
    }
  }