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())); }
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); }
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())); } } }
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"); } } }