[cfe-dev] clang via JNI + libclang-c

Anton Smirnov dev at antonsmirnov.name
Fri Oct 11 02:04:43 PDT 2013


It seems to be libclang or libclang+JNI problem as i'm experienced with JNI
and i checked packing/unpacking using my concrete class.


2013/10/11 Anton Smirnov <dev at antonsmirnov.name>

>  Well, that sounds like it will not work because of JNI?
>
> In few words, i'm trying to invoke indexing, parsing and tokenizing from
> java using libclang.
>
> // create index
>     native public static Index createIndex(boolean
> excludeDeclarationsFromPCH);
>
>     // parse translation unit from file
>     native public static TranslationUnit parseTranslationUnit(Index index,
> String filename, String[] commandLineArgs, UnsavedFile[] unsavedFiles);
>
>     // tokenize
>     native public static Token[] tokenize(TranslationUnit translationUnit,
> String filename, int filesize);
>
>     // dispose translation unit
>     native public static void dispose(TranslationUnit translationUnit);
>
>     // dispose index
>     native public static void dispose(Index index);
>
> for this methods there is native code with according methods and java
> nandles invocation from java code to native:
>
> /*
>  * Class:     name_antonsmirnov_clang_clang_wrapper
>  * Method:    createIndex
>  * Signature: (Z)Lname/antonsmirnov/clang/dto/Index;
>  */
> JNIEXPORT jobject JNICALL
> Java_name_antonsmirnov_clang_clang_1wrapper_createIndex
>   (JNIEnv *env, jobject obj, jboolean excludeDeclarationsFromPCH)
>   {
> ...
> }
>
> /*
>  * Class:     name_antonsmirnov_clang_clang_wrapper
>  * Method:    parseTranslationUnit
>  * Signature:
> (Lname/antonsmirnov/clang/dto/Index;Ljava/lang/String;[Lname/antonsmirnov/clang/dto/UnsavedFile;[Ljava/lang/String;)Lname/antonsmirnov/clang/dto/TranslationUnit;
>  */
> JNIEXPORT jobject
> Java_name_antonsmirnov_clang_clang_1wrapper_parseTranslationUnit
>   (JNIEnv *env, jobject obj, jobject jindex, jstring jfilename,
> jobjectArray commandLineArgs, jobjectArray unsavedFiles)
>   {
>
> ...
> }
>
> so i map classes from java to native code and vice versa.
> In native methods i invoke libclang-c methods.
>
> The problem is that CXIndex and CXTranslationUnit should be passed in the
> next methods so i have to keep them in memory in native code,
> pass pointer to java as long and then return back with casting long as
> pointer.
> I'm absolutely sure that pointers are packed/unpacked (long <--> pointer)
> correctly.
>
> The problem is that if i do in the same invocation from java (f.e. in
> single Java_name_antonsmirnov_clang_clang_1wrapper_tokenize() function) -
> it works good.
> For example if i just remember parameters and then create index, parse,
> tokenize (clang-c invocations) within tokenize() method it's okay.
>
> If i do everything in separate native methods (clang-c invocation in
> separate native calls from java) (as it's designed to do) pointers are
> corrupted.
> So unpacked CXIndex in parse() invocation is corrupted even if it was
> packed/unpacked correctly and the pointer is the same.
>
> Any thoughts? Is is libclang problem, jni problem or i'm doing smth wrong?
>
>
>
> 2013/10/11 Renato Golin <renato.golin at linaro.org>
>
>> On 11 October 2013 08:02, Anton Smirnov <dev at antonsmirnov.name> wrote:
>>
>>> Are there any obvious limitations or anybody with such experience?
>>>
>>
>> Yes, JNI.
>>
>> JNI is a poor implementation of C code, trying to deal with the poor
>> definitions of Java code, at the same time as trying to be 100%
>> cross-platform. It fails on all three levels.
>>
>> Stack corruption in JNI is surprisingly common, especially on Windows
>> (but also on Linux), and a few tricks must be used if you pass more than
>> just a char pointer. On the top of my head I remember I had to define a
>> large array on the stack, so that the stack pointer wouldn't segfault.
>>
>> JNI is also surprisingly poor in propagating errors from the C layer to
>> the Java layer (if at all), so catching errors and debugging the interface
>> is downright nightmare.
>>
>> You would hope that, after all these years, someone would come up with a
>> fix, or a better infrastructure for inter-operating C code with Java...
>>
>> This is a long shot, but have you tried using the VMKit and sharing C and
>> Java code via LLVM's Execution Engine? I heard of a project that managed to
>> do that with Python+C, including exception handling, so it should be
>> possible to do that with Java.
>>
>> cheers,
>> --renato
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131011/5a7be962/attachment.html>


More information about the cfe-dev mailing list