Пример #1
0
 private static void printParameterCaching(
     PrintWriter writer,
     TypeElement interface_decl,
     ExecutableElement method,
     Mode mode,
     boolean context_specific) {
   for (VariableElement param : method.getParameters()) {
     Class java_type = Utils.getJavaType(param.asType());
     CachedReference cachedReference = param.getAnnotation(CachedReference.class);
     if (Buffer.class.isAssignableFrom(java_type)
         && cachedReference != null
         && (mode != Mode.BUFFEROBJECT || param.getAnnotation(BufferObject.class) == null)
         && param.getAnnotation(Result.class) == null) {
       writer.print("\t\tif ( LWJGLUtil.CHECKS ) StateTracker.");
       if (context_specific) {
         writer.print("getReferences(caps).");
       } else {
         writer.print("getTracker().");
       }
       if (cachedReference.name().length() > 0) {
         writer.print(cachedReference.name());
       } else {
         writer.print(Utils.getReferenceName(interface_decl, method, param));
       }
       if (cachedReference.index().length() > 0) {
         writer.print("[" + cachedReference.index() + "]");
       }
       writer.println(" = " + param.getSimpleName() + ";");
     }
   }
 }
Пример #2
0
 private static String getResultType(ExecutableElement method, boolean native_stub) {
   if (native_stub && method.getAnnotation(PointerWrapper.class) != null) {
     return "long";
   } else if (!native_stub && method.getAnnotation(GLreturn.class) != null) {
     return Utils.getMethodReturnType(method, method.getAnnotation(GLreturn.class), false);
   } else {
     return Utils.getJavaType(Utils.getMethodReturnType(method)).getSimpleName();
   }
 }
 private static void generateStringDeallocations(
     PrintWriter writer, Collection<ParameterDeclaration> params) {
   for (ParameterDeclaration param : params) {
     if (Utils.getJavaType(param.getType()).equals(String.class)
         && param.getAnnotation(Result.class) == null)
       writer.println("\tfree(" + param.getSimpleName() + BUFFER_ADDRESS_POSTFIX + ");");
     else if (param.getAnnotation(StringList.class) != null) // Free the string array mem
     writer.println("\tfree(" + param.getSimpleName() + STRING_LIST_POSTFIX + ");");
   }
 }
Пример #4
0
 private static String getDefaultResultValue(ExecutableElement method) {
   if (method.getAnnotation(GLreturn.class) != null) {
     final String type =
         Utils.getMethodReturnType(method, method.getAnnotation(GLreturn.class), false);
     if ("boolean".equals(type)) {
       return "false";
     } else if (Character.isLowerCase(type.charAt(0))) {
       return "0";
     } else {
       return "null";
     }
   } else {
     final Class type = Utils.getJavaType(Utils.getMethodReturnType(method));
     if (type.isPrimitive()) {
       if (type == boolean.class) {
         return "false";
       } else {
         return "0";
       }
     } else {
       return "null";
     }
   }
 }
Пример #5
0
  private static void printParameterChecks(
      PrintWriter writer,
      ExecutableElement method,
      Map<VariableElement, TypeInfo> typeinfos,
      Mode mode,
      final boolean generate_error_checks) {
    if (mode == Mode.NORMAL) {
      final GenerateAutos gen_autos_annotation = method.getAnnotation(GenerateAutos.class);
      if (gen_autos_annotation != null && gen_autos_annotation.sizeVariables().length > 0) {
        // For the auto-generated parameters, declare and init a size variable (that can be reused
        // by @Code)
        for (final VariableElement param : method.getParameters()) {
          if (Arrays.binarySearch(
                  gen_autos_annotation.sizeVariables(), param.getSimpleName().toString())
              >= 0) {
            final int shifting = getBufferElementSizeExponent(typeinfos.get(param).getType());
            final Check check_annotation = param.getAnnotation(Check.class);

            writer.print("\t\tlong " + param.getSimpleName() + "_size = ");
            if (check_annotation == null || !check_annotation.canBeNull()) {
              writer.println(param.getSimpleName() + ".remaining() << " + shifting + ";");
            } else {
              writer.println(
                  param.getSimpleName()
                      + " == null ? 0 : "
                      + param.getSimpleName()
                      + ".remaining() << "
                      + shifting
                      + ";");
            }
          }
        }
      }
    }

    for (VariableElement param : method.getParameters()) {
      Class java_type = Utils.getJavaType(param.asType());
      if (java_type.isArray()
          || (Utils.isAddressableType(java_type)
              && (mode != Mode.BUFFEROBJECT || param.getAnnotation(BufferObject.class) == null)
              && (mode != Mode.AUTOS || getAutoTypeParameter(method, param) == null)
              && param.getAnnotation(Result.class) == null
              && !Utils.isReturnParameter(method, param))) {
        String check_value = null;
        boolean can_be_null = false;
        Check check_annotation = param.getAnnotation(Check.class);
        if (check_annotation != null) {
          check_value = check_annotation.value();
          can_be_null = check_annotation.canBeNull();
        }
        if ((Buffer.class.isAssignableFrom(java_type)
                || PointerBuffer.class.isAssignableFrom(java_type))
            && param.getAnnotation(Constant.class) == null) {
          TypeInfo typeinfo = typeinfos.get(param);
          printParameterCheck(
              writer,
              method,
              param.getSimpleName().toString(),
              typeinfo.getType().getSimpleName(),
              check_value,
              can_be_null,
              param.getAnnotation(NullTerminated.class),
              generate_error_checks);
        } else if (String.class.equals(java_type)) {
          if (!can_be_null) {
            writer.println("\t\tBufferChecks.checkNotNull(" + param.getSimpleName() + ");");
          }
        } else if (java_type.isArray()) {
          printArrayParameterCheck(
              writer, param.getSimpleName().toString(), check_value, can_be_null);
        }
      }
    }
    if (method.getAnnotation(CachedResult.class) != null) {
      printParameterCheck(
          writer, method, Utils.CACHED_BUFFER_NAME, null, null, true, null, generate_error_checks);
    }
  }
Пример #6
0
  private static void printMethodWithMultiType(
      ProcessingEnvironment env,
      TypeMap type_map,
      PrintWriter writer,
      TypeElement interface_decl,
      ExecutableElement method,
      Map<VariableElement, TypeInfo> typeinfos_instance,
      Mode mode,
      boolean generate_error_checks,
      boolean context_specific) {
    Utils.printDocComment(writer, method, env);
    if (method.getAnnotation(Deprecated.class) != null) {
      writer.println("\t@Deprecated");
    }
    if (interface_decl.getAnnotation(Private.class) == null
        && method.getAnnotation(Private.class) == null) {
      writer.print("\tpublic static ");
    } else {
      writer.print("\tstatic ");
    }
    writer.print(getResultType(method, false));
    StripPostfix strip_annotation = method.getAnnotation(StripPostfix.class);
    String method_name;
    Alternate alt_annotation = method.getAnnotation(Alternate.class);
    method_name =
        alt_annotation == null || alt_annotation.javaAlt()
            ? method.getSimpleName().toString()
            : alt_annotation.value();
    if (strip_annotation != null && mode == Mode.NORMAL) {
      method_name = getPostfixStrippedName(type_map, interface_decl, method);
    }
    writer.print(" " + method_name + "(");
    generateParametersJava(writer, method, typeinfos_instance, false, true, mode);
    writer.println(") {");

    final TypeMirror result_type = Utils.getMethodReturnType(method);
    boolean has_result = !result_type.equals(env.getTypeUtils().getNoType(TypeKind.VOID));

    final Reuse reuse_annotation = method.getAnnotation(Reuse.class);
    if (reuse_annotation != null) {
      writer.print("\t\t");
      if (has_result || method.getAnnotation(GLreturn.class) != null) {
        writer.print("return ");
      }

      writer.print(
          reuse_annotation.value()
              + "."
              + (reuse_annotation.method().length() > 0 ? reuse_annotation.method() : method_name)
              + "(");
      generateParametersJava(writer, method, typeinfos_instance, false, false, mode);
      writer.println(");\n\t}");
      return;
    }

    if (context_specific) {
      type_map.printCapabilitiesInit(writer);
      writer.print(
          "\t\tlong " + Utils.FUNCTION_POINTER_VAR_NAME + " = " + type_map.getCapabilities() + ".");
      writer.println(Utils.getFunctionAddressName(interface_decl, method, true) + ";");
      writer.print("\t\tBufferChecks.checkFunctionAddress(");
      writer.println(Utils.FUNCTION_POINTER_VAR_NAME + ");");
    }
    final Code code_annotation = method.getAnnotation(Code.class);
    if (code_annotation != null && code_annotation.value().length() > 0) {
      writer.println(code_annotation.value());
    }
    printBufferObjectChecks(writer, method, mode, context_specific);
    printParameterChecks(writer, method, typeinfos_instance, mode, generate_error_checks);
    printParameterCaching(writer, interface_decl, method, mode, context_specific);

    if (code_annotation != null && code_annotation.javaBeforeNative().length() > 0) {
      writer.println(code_annotation.javaBeforeNative());
    }
    writer.print("\t\t");

    final PointerWrapper pointer_wrapper_annotation = method.getAnnotation(PointerWrapper.class);
    if (has_result) {
      writer.print(getResultType(method, false) + " " + Utils.RESULT_VAR_NAME);

      if (code_annotation != null && code_annotation.tryBlock()) {
        writer.print(" = " + getDefaultResultValue(method));
        writer.println(";\n\t\ttry {");
        writer.print("\t\t\t" + Utils.RESULT_VAR_NAME);
      }

      writer.print(" = ");
      if (pointer_wrapper_annotation != null) {
        if (pointer_wrapper_annotation.factory().length() > 0) {
          writer.print(pointer_wrapper_annotation.factory() + "(");
        } else {
          writer.print("new " + getResultType(method, false) + "(");
        }
      }
    } else if (method.getAnnotation(GLreturn.class) != null) {
      has_result = true;
      Utils.printGLReturnPre(writer, method, method.getAnnotation(GLreturn.class), type_map);
    }
    writer.print(Utils.getSimpleNativeMethodName(method, generate_error_checks, context_specific));
    if (mode == Mode.BUFFEROBJECT) {
      writer.print(Utils.BUFFER_OBJECT_METHOD_POSTFIX);
    }
    writer.print("(");
    boolean first_parameter =
        printMethodCallArguments(writer, method, typeinfos_instance, mode, type_map);
    if (context_specific) {
      if (!first_parameter) {
        writer.print(", ");
      }
      writer.print(Utils.FUNCTION_POINTER_VAR_NAME);
    }
    if (has_result && pointer_wrapper_annotation != null) {
      writer.print(")");
      if (pointer_wrapper_annotation.params().length() > 0) {
        writer.print(", " + pointer_wrapper_annotation.params());
      }
    }
    writer.println(");");

    if (code_annotation != null && code_annotation.javaAfterNative().length() > 0) {
      writer.println(code_annotation.javaAfterNative());
    }

    final String tabs = code_annotation != null && code_annotation.tryBlock() ? "\t\t\t" : "\t\t";
    if (generate_error_checks && method.getAnnotation(NoErrorCheck.class) == null) {
      type_map.printErrorCheckMethod(writer, method, tabs);
    }
    // DISABLED: indirect buffer support
    // printNondirectParameterCopies(writer, method, mode);
    if (has_result) {
      if (method.getAnnotation(GLreturn.class) == null) {
        if (ByteBuffer.class.equals(Utils.getJavaType(result_type))) {
          writer.println(
              tabs
                  + "return LWJGLUtil.CHECKS && "
                  + Utils.RESULT_VAR_NAME
                  + " == null ? null : "
                  + Utils.RESULT_VAR_NAME
                  + ".order(ByteOrder.nativeOrder());"); // safeNewBuffer returns a direct
                                                         // ByteBuffer with BIG_ENDIAN order.
        } else {
          writer.println(tabs + "return " + Utils.RESULT_VAR_NAME + ";");
        }
      } else {
        Utils.printGLReturnPost(writer, method, method.getAnnotation(GLreturn.class), type_map);
      }
    }

    if (code_annotation != null && code_annotation.tryBlock()) {
      writer.println("\t\t} finally {");
      writer.println(code_annotation.javaFinally());
      writer.println("\t\t}");
    }
    writer.println("\t}");
  }
  private static boolean generateBufferParameterAddress(
      TypeMap type_map,
      PrintWriter writer,
      MethodDeclaration method,
      ParameterDeclaration param,
      Mode mode,
      boolean loopDeclared) {
    NativeTypeTranslator translator = new NativeTypeTranslator(type_map, param);
    param.getType().accept(translator);
    writer.print("\t" + translator.getSignature() + param.getSimpleName());
    writer.print(BUFFER_ADDRESS_POSTFIX + " = ((");
    writer.print(translator.getSignature());
    Check check_annotation = param.getAnnotation(Check.class);
    writer.print(")");
    if (mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null) {
      writer.print(
          "offsetToPointer("
              + param.getSimpleName()
              + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX
              + "))");
    } else {
      Class java_type = Utils.getJavaType(param.getType());
      if (Buffer.class.isAssignableFrom(java_type)
          || java_type.equals(CharSequence.class)
          || java_type.equals(CharSequence[].class)) {
        boolean explicitly_byte_sized =
            java_type.equals(Buffer.class)
                || translator.getAnnotationType().equals(type_map.getVoidType());
        if (explicitly_byte_sized) writer.print("(((char *)");
        if (method.getAnnotation(GenerateAutos.class) != null
            || (check_annotation != null && check_annotation.canBeNull())) {
          writer.print("safeGetBufferAddress(env, " + param.getSimpleName());
        } else {
          writer.print("(*env)->GetDirectBufferAddress(env, " + param.getSimpleName());
        }
        writer.print("))");
        writer.print(" + " + param.getSimpleName() + BUFFER_POSITION_POSTFIX);
        if (explicitly_byte_sized) writer.print("))");
      } else if (java_type.equals(String.class)) {
        writer.print("GetStringNativeChars(env, " + param.getSimpleName() + "))");
      } else throw new RuntimeException("Illegal type " + java_type);
    }
    writer.println(";");

    if (param.getAnnotation(StringList.class) != null) {
      if (Utils.getJavaType(param.getType()) != CharSequence[].class
          && (param.getAnnotation(GLchar.class) == null
              || param.getAnnotation(NullTerminated.class) == null
              || param.getAnnotation(NullTerminated.class).value().length() == 0))
        throw new RuntimeException(
            "StringList annotation can only be applied on null-terminated GLchar buffers.");

      if ("_str".equals(param.getSimpleName()))
        throw new RuntimeException(
            "The name '_str' is not valid for arguments annotated with StringList");

      // Declare loop counters and allocate string array
      if (!loopDeclared) {
        writer.println("\tunsigned int _str_i;");
        writer.println("\tGLchar *_str_address;");
        loopDeclared = true;
      }
      writer.println(
          "\tGLchar **"
              + param.getSimpleName()
              + STRING_LIST_POSTFIX
              + " = (GLchar **) malloc("
              + param.getAnnotation(StringList.class).value()
              + "*sizeof(GLchar*));");
    }
    return loopDeclared;
  }
  private static void generateMethodStub(
      AnnotationProcessorEnvironment env,
      TypeMap type_map,
      PrintWriter writer,
      String interface_name,
      MethodDeclaration method,
      Mode mode,
      boolean generate_error_checks,
      boolean context_specific) {
    if (!context_specific && method.getAnnotation(Alternate.class) == null) writer.print("static ");
    else writer.print("JNIEXPORT ");

    TypeMirror result_type = Utils.getMethodReturnType(method);

    if (method.getAnnotation(GLpointer.class) != null) {
      writer.print("jlong");
    } else {
      JNITypeTranslator translator = new JNITypeTranslator();
      result_type.accept(translator);
      writer.print(translator.getSignature());
    }
    writer.print(" JNICALL ");

    writer.print(
        Utils.getQualifiedNativeMethodName(
            interface_name, method, generate_error_checks, context_specific));
    if (mode == Mode.BUFFEROBJECT) writer.print(Utils.BUFFER_OBJECT_METHOD_POSTFIX);
    writer.print("(JNIEnv *env, jclass clazz");
    generateParameters(writer, method.getParameters(), mode);
    if (Utils.getNIOBufferType(result_type) != null) {
      CachedResult cached_result_annotation = method.getAnnotation(CachedResult.class);
      if (cached_result_annotation == null || !cached_result_annotation.isRange())
        writer.print(", jlong " + Utils.RESULT_SIZE_NAME);
      if (cached_result_annotation != null) writer.print(", jobject " + Utils.CACHED_BUFFER_NAME);
    }
    if (context_specific) {
      writer.print(", jlong " + Utils.FUNCTION_POINTER_VAR_NAME);
    }
    writer.println(") {");
    generateBufferParameterAddresses(type_map, writer, method, mode);
    Alternate alt_annotation = method.getAnnotation(Alternate.class);
    if (context_specific) {
      String typedef_name = Utils.getTypedefName(method);
      writer.print(
          "\t"
              + typedef_name
              + " "
              + (alt_annotation == null ? method.getSimpleName() : alt_annotation.value()));
      writer.print(" = (" + typedef_name + ")((intptr_t)");
      writer.println(Utils.FUNCTION_POINTER_VAR_NAME + ");");
    }
    generateStringListInits(writer, method.getParameters());
    writer.print("\t");
    if (!result_type.equals(env.getTypeUtils().getVoidType())) {
      Declaration return_declaration;
      ParameterDeclaration result_param = Utils.getResultParameter(method);
      if (result_param != null) return_declaration = result_param;
      else return_declaration = method;
      NativeTypeTranslator native_translator =
          new NativeTypeTranslator(type_map, return_declaration);
      result_type.accept(native_translator);
      writer.print(native_translator.getSignature() + " " + Utils.RESULT_VAR_NAME);
      if (result_param != null) {
        writer.println(";");
        writer.print("\t");
      } else writer.print(" = ");
    }
    writer.print((alt_annotation == null ? method.getSimpleName() : alt_annotation.value()) + "(");
    generateCallParameters(writer, type_map, method.getParameters());
    writer.print(")");
    writer.println(";");
    generateStringDeallocations(writer, method.getParameters());
    if (!result_type.equals(env.getTypeUtils().getVoidType())) {
      writer.print("\treturn ");
      Class java_result_type = Utils.getJavaType(result_type);
      if (Buffer.class.isAssignableFrom(java_result_type)) {
        if (method.getAnnotation(CachedResult.class) != null)
          writer.print("safeNewBufferCached(env, ");
        else writer.print("safeNewBuffer(env, ");
      } else if (String.class.equals(java_result_type)) {
        writer.print("NewStringNativeUnsigned(env, ");
      } else if (method.getAnnotation(GLpointer.class) != null) {
        writer.print("(intptr_t)");
      }
      writer.print(Utils.RESULT_VAR_NAME);
      if (Buffer.class.isAssignableFrom(java_result_type)) {
        writer.print(", ");
        if (method.getAnnotation(CachedResult.class) != null
            && method.getAnnotation(CachedResult.class).isRange())
          Utils.printExtraCallArguments(
              writer, method, method.getAnnotation(AutoResultSize.class).value());
        else Utils.printExtraCallArguments(writer, method, Utils.RESULT_SIZE_NAME);
      }
      if (Buffer.class.isAssignableFrom(java_result_type) || String.class.equals(java_result_type))
        writer.print(")");
      writer.println(";");
    }
    writer.println("}");
    writer.println();
  }