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 >> >
