Esempio n. 1
0
  static void emitFromNativeConversion(
      AsmBuilder builder,
      SkinnyMethodAdapter mv,
      FromNativeType fromNativeType,
      Class nativeClass) {
    // If there is a result converter, retrieve it and put on the stack
    FromNativeConverter fromNativeConverter = fromNativeType.getFromNativeConverter();
    if (fromNativeConverter != null) {
      convertPrimitive(
          mv,
          nativeClass,
          unboxedType(fromNativeConverter.nativeType()),
          fromNativeType.getNativeType());
      boxValue(builder, mv, fromNativeConverter.nativeType(), nativeClass);

      Method fromNativeMethod = getFromNativeMethod(fromNativeType, builder.getClassLoader());
      getfield(mv, builder, builder.getFromNativeConverterField(fromNativeConverter));
      mv.swap();
      if (fromNativeType.getFromNativeContext() != null) {
        getfield(
            mv, builder, builder.getFromNativeContextField(fromNativeType.getFromNativeContext()));
      } else {
        mv.aconst_null();
      }

      if (fromNativeMethod.getDeclaringClass().isInterface()) {
        mv.invokeinterface(
            fromNativeMethod.getDeclaringClass(),
            fromNativeMethod.getName(),
            fromNativeMethod.getReturnType(),
            fromNativeMethod.getParameterTypes());
      } else {
        mv.invokevirtual(
            fromNativeMethod.getDeclaringClass(),
            fromNativeMethod.getName(),
            fromNativeMethod.getReturnType(),
            fromNativeMethod.getParameterTypes());
      }

      if (fromNativeType.getDeclaredType().isPrimitive()) {
        // The actual return type is a primitive, but there was a converter for it - extract the
        // primitive value
        Class boxedType = getBoxedClass(fromNativeType.getDeclaredType());
        if (!boxedType.isAssignableFrom(fromNativeMethod.getReturnType()))
          mv.checkcast(p(boxedType));
        unboxNumber(
            mv, boxedType, fromNativeType.getDeclaredType(), fromNativeType.getNativeType());

      } else if (!fromNativeType
          .getDeclaredType()
          .isAssignableFrom(fromNativeMethod.getReturnType())) {
        mv.checkcast(p(fromNativeType.getDeclaredType()));
      }

    } else if (!fromNativeType.getDeclaredType().isPrimitive()) {
      Class unboxedType = unboxedType(fromNativeType.getDeclaredType());
      convertPrimitive(mv, nativeClass, unboxedType, fromNativeType.getNativeType());
      boxValue(builder, mv, fromNativeType.getDeclaredType(), unboxedType);
    }
  }
Esempio n. 2
0
  static Method getFromNativeMethod(FromNativeType fromNativeType, AsmClassLoader classLoader) {
    FromNativeConverter fromNativeConverter = fromNativeType.getFromNativeConverter();
    if (fromNativeConverter == null) {
      return null;
    }

    try {
      Class<? extends FromNativeConverter> fromNativeConverterClass =
          fromNativeConverter.getClass();
      if (Modifier.isPublic(fromNativeConverterClass.getModifiers())) {
        for (Method method : fromNativeConverterClass.getMethods()) {
          if (!method.getName().equals("fromNative")) continue;
          Class[] methodParameterTypes = method.getParameterTypes();
          Class javaType =
              fromNativeType.getDeclaredType().isPrimitive()
                  ? boxedType(fromNativeType.getDeclaredType())
                  : fromNativeType.getDeclaredType();
          if (javaType.isAssignableFrom(method.getReturnType())
              && methodParameterTypes.length == 2
              && methodParameterTypes[0].isAssignableFrom(fromNativeConverter.nativeType())
              && methodParameterTypes[1] == FromNativeContext.class
              && methodIsAccessible(method)
              && classIsVisible(classLoader, method.getDeclaringClass())) {
            return method;
          }
        }
      }
      Method method =
          fromNativeConverterClass.getMethod("fromNative", Object.class, FromNativeContext.class);
      return methodIsAccessible(method) && classIsVisible(classLoader, method.getDeclaringClass())
          ? method
          : FromNativeConverter.class.getDeclaredMethod(
              "fromNative", Object.class, FromNativeContext.class);

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