예제 #1
0
파일: ProxyMaker.java 프로젝트: int3/jython
  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);
    }
  }
예제 #2
0
파일: ProxyMaker.java 프로젝트: int3/jython
  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);
    }
  }
예제 #3
0
파일: ProxyMaker.java 프로젝트: int3/jython
  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_();
  }
예제 #4
0
파일: ProxyMaker.java 프로젝트: int3/jython
  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);
    }
  }
예제 #5
0
파일: ProxyMaker.java 프로젝트: int3/jython
 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));
 }