예제 #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);
    }
  }
예제 #2
0
 public static ClassVisitor newCheckClassAdapter(ClassVisitor cv) {
   try {
     Class<? extends ClassVisitor> tmvClass =
         Class.forName("org.objectweb.asm.util.CheckClassAdapter").asSubclass(ClassVisitor.class);
     Constructor<? extends ClassVisitor> c = tmvClass.getDeclaredConstructor(ClassVisitor.class);
     return c.newInstance(cv);
   } catch (Throwable t) {
     return cv;
   }
 }
예제 #3
0
  public static ClassVisitor newTraceClassVisitor(PrintWriter out) {
    try {

      Class<? extends ClassVisitor> tmvClass =
          Class.forName("org.objectweb.asm.util.TraceClassVisitor").asSubclass(ClassVisitor.class);
      Constructor<? extends ClassVisitor> c = tmvClass.getDeclaredConstructor(PrintWriter.class);
      return c.newInstance(out);
    } catch (Throwable t) {
      throw new RuntimeException(t);
    }
  }
예제 #4
0
 public static MethodVisitor newTraceMethodVisitor(MethodVisitor mv) {
   try {
     Class<? extends MethodVisitor> tmvClass =
         Class.forName("org.objectweb.asm.util.TraceMethodVisitor")
             .asSubclass(MethodVisitor.class);
     Constructor<? extends MethodVisitor> c = tmvClass.getDeclaredConstructor(MethodVisitor.class);
     return c.newInstance(mv);
   } catch (Throwable t) {
     return mv;
   }
 }
예제 #5
0
  static void emitReturn(
      AsmBuilder builder, SkinnyMethodAdapter mv, Class returnType, Class nativeIntType) {
    if (returnType.isPrimitive()) {

      if (long.class == returnType) {
        mv.lreturn();

      } else if (float.class == returnType) {
        mv.freturn();

      } else if (double.class == returnType) {
        mv.dreturn();

      } else if (void.class == returnType) {
        mv.voidreturn();

      } else {
        mv.ireturn();
      }

    } else {
      boxValue(builder, mv, returnType, nativeIntType);
      mv.areturn();
    }
  }
예제 #6
0
  private static boolean classIsVisible(ClassLoader classLoader, Class klass) {
    try {
      return classLoader.loadClass(klass.getName()) == klass;

    } catch (ClassNotFoundException cnfe) {
      return false;
    }
  }
예제 #7
0
  static boolean isDelegate(Class klass) {
    for (Method m : klass.getMethods()) {
      if (m.isAnnotationPresent(Delegate.class)) {
        return true;
      }
    }

    return false;
  }
예제 #8
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");
      }
    }
  }
예제 #9
0
 static void emitReturnOp(SkinnyMethodAdapter mv, Class returnType) {
   if (!returnType.isPrimitive()) {
     mv.areturn();
   } else if (long.class == returnType) {
     mv.lreturn();
   } else if (float.class == returnType) {
     mv.freturn();
   } else if (double.class == returnType) {
     mv.dreturn();
   } else if (void.class == returnType) {
     mv.voidreturn();
   } else {
     mv.ireturn();
   }
 }
예제 #10
0
  static void store(SkinnyMethodAdapter mv, Class type, LocalVariable var) {
    if (!type.isPrimitive()) {
      mv.astore(var);

    } else if (long.class == type) {
      mv.lstore(var);

    } else if (double.class == type) {
      mv.dstore(var);

    } else if (float.class == type) {
      mv.fstore(var);

    } else {
      mv.istore(var);
    }
  }
예제 #11
0
  static void load(SkinnyMethodAdapter mv, Class parameterType, LocalVariable parameter) {
    if (!parameterType.isPrimitive()) {
      mv.aload(parameter);

    } else if (long.class == parameterType) {
      mv.lload(parameter);

    } else if (float.class == parameterType) {
      mv.fload(parameter);

    } else if (double.class == parameterType) {
      mv.dload(parameter);

    } else {
      mv.iload(parameter);
    }
  }
예제 #12
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");
      }
    }
  }
예제 #13
0
  static void boxValue(
      AsmBuilder builder, SkinnyMethodAdapter mv, Class boxedType, Class unboxedType) {
    if (boxedType == unboxedType || boxedType.isPrimitive()) {

    } else if (Boolean.class.isAssignableFrom(boxedType)) {
      narrow(mv, unboxedType, boolean.class);
      mv.invokestatic(Boolean.class, "valueOf", Boolean.class, boolean.class);

    } else if (Pointer.class.isAssignableFrom(boxedType)) {
      getfield(mv, builder, builder.getRuntimeField());
      mv.invokestatic(
          AsmRuntime.class, "pointerValue", Pointer.class, unboxedType, jnr.ffi.Runtime.class);

    } else if (Address.class == boxedType) {
      mv.invokestatic(boxedType, "valueOf", boxedType, unboxedType);

    } else if (Number.class.isAssignableFrom(boxedType) && boxedType(unboxedType) == boxedType) {
      mv.invokestatic(boxedType, "valueOf", boxedType, unboxedType);

    } else {
      throw new IllegalArgumentException(
          "cannot box value of type " + unboxedType + " to " + boxedType);
    }
  }