public void appendToSignature( int iParam, ValueType type, Class<?> parameterType, Type genericParameterType, StringBuilder javaSig, StringBuilder dcSig, StringBuilder asmSig) { char dcChar; String javaChar, asmChar = null; switch (type) { case eVoidValue: dcChar = DC_SIGCHAR_VOID; javaChar = "V"; break; case eIntValue: dcChar = DC_SIGCHAR_INT; javaChar = "I"; break; case eLongValue: dcChar = DC_SIGCHAR_LONGLONG; javaChar = "J"; break; case eSizeTValue: javaChar = "J"; if (Platform.SIZE_T_SIZE == 8) { dcChar = DC_SIGCHAR_LONGLONG; } else { dcChar = DC_SIGCHAR_INT; direct = false; } break; case eShortValue: dcChar = DC_SIGCHAR_SHORT; javaChar = "S"; break; case eDoubleValue: dcChar = DC_SIGCHAR_DOUBLE; javaChar = "D"; break; case eFloatValue: dcChar = DC_SIGCHAR_FLOAT; javaChar = "F"; break; case eByteValue: dcChar = DC_SIGCHAR_CHAR; javaChar = "B"; break; case eBooleanValue: dcChar = DC_SIGCHAR_BOOL; javaChar = "Z"; break; case eWCharValue: switch (Platform.WCHAR_T_SIZE) { case 1: dcChar = DC_SIGCHAR_CHAR; direct = false; break; case 2: dcChar = DC_SIGCHAR_SHORT; break; case 4: dcChar = DC_SIGCHAR_INT; direct = false; break; default: throw new RuntimeException( "Unhandled sizeof(wchar_t) in GetJavaTypeSignature: " + Platform.WCHAR_T_SIZE); } javaChar = "C"; break; case eIntFlagSet: dcChar = DC_SIGCHAR_INT; javaChar = "L" + parameterType.getName().replace('.', '/') + ";"; // "Lorg/bridj/ValuedEnum;"; direct = false; break; case eCLongObjectValue: dcChar = DC_SIGCHAR_POINTER; javaChar = "Lorg/bridj/CLong;"; direct = false; break; case eSizeTObjectValue: dcChar = DC_SIGCHAR_POINTER; javaChar = "Lorg/bridj/SizeT;"; direct = false; break; case eTimeTObjectValue: dcChar = DC_SIGCHAR_POINTER; javaChar = "Lorg/bridj/TimeT;"; direct = false; break; case ePointerValue: dcChar = DC_SIGCHAR_POINTER; javaChar = "L" + parameterType.getName().replace('.', '/') + ";"; // javaChar = "Lorg/bridj/Pointer;"; direct = false; break; case eNativeObjectValue: dcChar = DC_SIGCHAR_STRUCT; // TODO : unroll struct signature ? javaChar = "L" + parameterType.getName().replace('.', '/') + ";"; direct = false; // if (parameterType.equals(declaringClass)) { // // special case of self-returning pointers // dcChar = DC_SIGCHAR_POINTER; break; case eEllipsis: javaChar = "[Ljava/lang/Object;"; dcChar = '?'; break; default: direct = false; throw new RuntimeException("Unhandled " + ValueType.class.getSimpleName() + ": " + type); } if (genericParameterType instanceof ParameterizedType && iParam < 0) { ParameterizedType pt = (ParameterizedType) genericParameterType; // TODO handle all cases !!! Type[] ts = pt.getActualTypeArguments(); if (ts != null && ts.length == 1) { Type t = ts[0]; if (t instanceof ParameterizedType) t = ((ParameterizedType) t).getRawType(); if (t instanceof Class) { Class c = (Class) t; if (javaChar.endsWith(";")) { asmChar = javaChar.substring(0, javaChar.length() - 1) + "<*L" + c.getName().replace('.', '/') + ";>"; // asmChar += ";"; } } } } if (javaSig != null) javaSig.append(javaChar); if (asmChar == null) asmChar = javaChar; if (asmSig != null) asmSig.append(asmChar); if (dcSig != null) dcSig.append(dcChar); }
protected void init( AnnotatedElement annotatedElement, Class returnType, Type genericReturnType, Annotation[] returnAnnotations, Class[] parameterTypes, Type[] genericParameterTypes, Annotation[][] paramsAnnotations, boolean prependJNIPointers, boolean isVirtual, boolean isDirectModeAllowed) { assert returnType != null; assert genericReturnType != null; assert parameterTypes != null; assert genericParameterTypes != null; assert returnAnnotations != null; assert parameterTypes.length == genericParameterTypes.length; assert paramsAnnotations.length == genericParameterTypes.length; int nParams = genericParameterTypes.length; paramsValueTypes = new int[nParams]; direct = isDirectModeAllowed; // TODO on native side : test number of parameters (on 64 bits win : // must be <= 4) StringBuilder javaSig = new StringBuilder(64), asmSig = new StringBuilder(64), dcSig = new StringBuilder(16); javaSig.append('('); asmSig.append('('); if (prependJNIPointers) // !isCPlusPlus) dcSig .append(DC_SIGCHAR_POINTER) .append(DC_SIGCHAR_POINTER); // JNIEnv*, jobject: always present in native-bound functions if (BridJ.debug) BridJ.info( "Analyzing " + (declaringClass == null ? "anonymous method" : declaringClass.getName() + "." + methodName)); if (isObjCBlock) appendToSignature( 0, ValueType.ePointerValue, Pointer.class, Pointer.class, null, dcSig, null); for (int iParam = 0; iParam < nParams; iParam++) { // Options paramOptions = paramsOptions[iParam] = new Options(); Type genericParameterType = genericParameterTypes[iParam]; Class<?> parameterType = parameterTypes[iParam]; ValueType paramValueType = getValueType( iParam, nParams, parameterType, genericParameterType, null, paramsAnnotations[iParam]); if (BridJ.veryVerbose) BridJ.info("\tparam " + paramValueType); paramsValueTypes[iParam] = paramValueType.ordinal(); appendToSignature( iParam, paramValueType, parameterType, genericParameterType, javaSig, dcSig, asmSig); } javaSig.append(')'); asmSig.append(')'); dcSig.append(')'); ValueType retType = getValueType( -1, nParams, returnType, genericReturnType, annotatedElement, returnAnnotations); if (BridJ.veryVerbose) BridJ.info("\treturns " + retType); appendToSignature(-1, retType, returnType, genericReturnType, javaSig, dcSig, asmSig); returnValueType = retType.ordinal(); javaSignature = javaSig.toString(); asmSignature = asmSig.toString(); dcSignature = dcSig.toString(); isCPlusPlus = isCPlusPlus || isVirtual; if (isCPlusPlus && !isStatic) { if (!startsWithThis) direct = false; bNeedsThisPointer = true; if (Platform.isWindows()) { if (!Platform.is64Bits()) setDcCallingConvention(DC_CALL_C_X86_WIN32_THIS_MS); } else { // if (!Platform.is64Bits()) // setDcCallingConvention(DC_CALL_C_X86_WIN32_THIS_GNU); } } if (nParams > Platform.getMaxDirectMappingArgCount()) this.direct = false; if (BridJ.veryVerbose) { BridJ.info("\t-> direct " + direct); BridJ.info("\t-> javaSignature " + javaSignature); BridJ.info("\t-> callIOs " + callIOs); BridJ.info("\t-> asmSignature " + asmSignature); BridJ.info("\t-> dcSignature " + dcSignature); } if (BridJ.veryVerbose) BridJ.info((direct ? "[mappable as direct] " : "[not mappable as direct] ") + method); }