示例#1
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);
    }
  }