Ejemplo 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);
    }
  }
Ejemplo n.º 2
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);
    }
  }