This is a lowering bug. I have a repro and a patch that fixes it (Pkg.test
JavaCall succeeds), but may have unforeseen side-effects. Will file an
issue or a PR soon once I do a bit more testing.

(there's also a work-around: use a different variable name for the ccall
ptr argument)

On Wed, Jun 29, 2016 at 6:43 PM, Avik Sengupta <[email protected]>
wrote:

> I'd like to bump this and see if anyone has any ideas. I do not see what
> could change.
>
> To provide some background, if it would help,
>
> The code referenced by Eric runs at load time, to generate a set of
> methods (called _jcall) for different types of inputs. For each such input
> type, a method definition is created within a quote block, and then that
> quote block is eval-ed to actually define the method.
>
> The reason separate functions are defined, rather than doing this by
> dynamic dispatch, is that a key part of the method is a ccall. The argument
> types to the ccall needs to be determined at compile time, and hence in
> this case we define a separate method for each input type, rather than use
> dynamic dispatch. This code works correctly in 0.4 (and 0.3), but fails
> with an UndefRefError in 0.5.
>
> Any ideas?
>
> Thanks!
> -
> Avik
>
>
> On Friday, 24 June 2016 19:50:01 UTC+1, Eric Davies wrote:
>>
>> I have an intuition that this should be possible because the ccall
>> depends on the input types, but I can't figure out how to make it work.
>> I've tried a few things and they all seem to result in an UndefVarError or
>> UndefRefError.
>>
>> I want to turn this:
>> for (x, y, z) in [ (:jboolean, :(jnifunc.CallBooleanMethodA), :(jnifunc.
>> CallStaticBooleanMethodA)),
>>                   (:jchar, :(jnifunc.CallCharMethodA), :(jnifunc.
>> CallStaticCharMethodA)),
>>                   (:jbyte, :(jnifunc.CallByteMethodA), :(jnifunc.
>> CallStaticByteMethodA)),
>>                   (:jshort, :(jnifunc.CallShortMethodA), :(jnifunc.
>> CallStaticShortMethodA)),
>>                   (:jint, :(jnifunc.CallIntMethodA), :(jnifunc.
>> CallStaticIntMethodA)),
>>                   (:jlong, :(jnifunc.CallLongMethodA), :(jnifunc.
>> CallStaticLongMethodA)),
>>                   (:jfloat, :(jnifunc.CallFloatMethodA), :(jnifunc.
>> CallStaticFloatMethodA)),
>>                   (:jdouble, :(jnifunc.CallDoubleMethodA), :(jnifunc.
>> CallStaticDoubleMethodA)),
>>                   (:Void, :(jnifunc.CallVoidMethodA), :(jnifunc.
>> CallStaticVoidMethodA)) ]
>>     m = quote
>>         function _jcall(obj,  jmethodId::Ptr{Void}, callmethod::Ptr{Void
>> }, rettype::Type{$(x)}, argtypes::Tuple, args... )
>>             if callmethod == C_NULL #!
>>                 callmethod = ifelse( typeof(obj)<:JavaObject, $y , $z )
>>             end
>>             @assert callmethod != C_NULL
>>             @assert jmethodId != C_NULL
>>             if(isnull(obj)); error("Attempt to call method on Java NULL"
>> ); end
>>             savedArgs, convertedArgs = convert_args(argtypes, args...)
>>             result = ccall(callmethod, $x , (Ptr{JNIEnv}, Ptr{Void}, Ptr{
>> Void}, Ptr{Void}), penv, obj.ptr, jmethodId, convertedArgs)
>>             if result==C_NULL; geterror(); end
>>             if result == nothing; return; end
>>             return convert_result(rettype, result)
>>         end
>>     end
>>     eval(m)
>> end
>>
>> Into something that works on 0.5. Code located here:
>> https://github.com/invenia/JavaCall.jl/blob/compat-0.5/src/core.jl#L196
>>
>> I've learned tricks to deal with the 0.4 function eval pattern, but they
>> don't seem to work with ccall, which is a special feature that requires
>> some arguments to be static and known at compile time.
>>
>> Anyone have any tips?
>>
>> Thanks,
>> Eric
>>
>

Reply via email to