예제 #1
0
 static com.kenai.jffi.Type getNativeResultType(
     NativeRuntime runtime, Method m, TypeMapper typeMapper) {
   ToNativeConverter converter =
       getToNativeConverter(m.getReturnType(), m.getAnnotations(), typeMapper);
   Class javaClass = converter != null ? converter.nativeType() : m.getReturnType();
   return jffiType(InvokerUtil.getNativeType(runtime, m.getReturnType(), m.getAnnotations()));
 }
예제 #2
0
 static ToNativeType getResultType(NativeRuntime runtime, Method m, TypeMapper typeMapper) {
   Annotation[] annotations = m.getAnnotations();
   ToNativeConverter converter = getToNativeConverter(m.getReturnType(), annotations, typeMapper);
   Class javaClass = converter != null ? converter.nativeType() : m.getReturnType();
   NativeType nativeType = InvokerUtil.getNativeType(runtime, javaClass, annotations);
   return new ToNativeType(m.getReturnType(), nativeType, annotations, converter);
 }
예제 #3
0
  static void emitToNativeConversion(
      AsmBuilder builder, SkinnyMethodAdapter mv, ToNativeType toNativeType) {
    ToNativeConverter parameterConverter = toNativeType.getToNativeConverter();
    if (parameterConverter != null) {
      Method toNativeMethod = getToNativeMethod(toNativeType, builder.getClassLoader());

      if (toNativeType.getDeclaredType().isPrimitive()) {
        boxValue(
            builder,
            mv,
            getBoxedClass(toNativeType.getDeclaredType()),
            toNativeType.getDeclaredType());
      }
      if (!toNativeMethod.getParameterTypes()[0].isAssignableFrom(
          getBoxedClass(toNativeType.getDeclaredType()))) {
        mv.checkcast(toNativeMethod.getParameterTypes()[0]);
      }

      mv.aload(0);
      AsmBuilder.ObjectField toNativeConverterField =
          builder.getToNativeConverterField(parameterConverter);
      mv.getfield(
          builder.getClassNamePath(),
          toNativeConverterField.name,
          ci(toNativeConverterField.klass));
      if (!toNativeMethod.getDeclaringClass().equals(toNativeConverterField.klass)) {
        mv.checkcast(toNativeMethod.getDeclaringClass());
      }

      // Re-order so the value to be converted is on the top of the stack
      mv.swap();

      // load context parameter (if there is one)
      if (toNativeType.getToNativeContext() != null) {
        getfield(mv, builder, builder.getToNativeContextField(toNativeType.getToNativeContext()));
      } else {
        mv.aconst_null();
      }

      if (toNativeMethod.getDeclaringClass().isInterface()) {
        mv.invokeinterface(
            toNativeMethod.getDeclaringClass(),
            toNativeMethod.getName(),
            toNativeMethod.getReturnType(),
            toNativeMethod.getParameterTypes());
      } else {
        mv.invokevirtual(
            toNativeMethod.getDeclaringClass(),
            toNativeMethod.getName(),
            toNativeMethod.getReturnType(),
            toNativeMethod.getParameterTypes());
      }
      if (!parameterConverter.nativeType().isAssignableFrom(toNativeMethod.getReturnType())) {
        mv.checkcast(p(parameterConverter.nativeType()));
      }
    }
  }
예제 #4
0
  static Method getToNativeMethod(ToNativeType toNativeType, AsmClassLoader classLoader) {
    ToNativeConverter toNativeConverter = toNativeType.getToNativeConverter();
    if (toNativeConverter == null) {
      return null;
    }

    try {
      Class<? extends ToNativeConverter> toNativeConverterClass = toNativeConverter.getClass();
      if (Modifier.isPublic(toNativeConverterClass.getModifiers())) {
        for (Method method : toNativeConverterClass.getMethods()) {
          if (!method.getName().equals("toNative")) continue;
          Class[] methodParameterTypes = method.getParameterTypes();
          if (toNativeConverter.nativeType().isAssignableFrom(method.getReturnType())
              && methodParameterTypes.length == 2
              && methodParameterTypes[0].isAssignableFrom(toNativeType.getDeclaredType())
              && methodParameterTypes[1] == ToNativeContext.class
              && methodIsAccessible(method)
              && classIsVisible(classLoader, method.getDeclaringClass())) {
            return method;
          }
        }
      }
      Method method =
          toNativeConverterClass.getMethod("toNative", Object.class, ToNativeContext.class);
      return methodIsAccessible(method) && classIsVisible(classLoader, method.getDeclaringClass())
          ? method
          : ToNativeConverter.class.getDeclaredMethod(
              "toNative", Object.class, ToNativeContext.class);

    } catch (NoSuchMethodException nsme) {
      try {
        return ToNativeConverter.class.getDeclaredMethod(
            "toNative", Object.class, ToNativeContext.class);
      } catch (NoSuchMethodException nsme2) {
        throw new RuntimeException(
            "internal error. " + ToNativeConverter.class + " has no toNative() method");
      }
    }
  }