@@ -332,166 +332,128 @@ function jnew(T::Symbol, argtypes::Tuple = () , args...)
332
332
if jmethodId == C_NULL
333
333
throw (JavaCallError (" No constructor for $T with signature $sig " ))
334
334
end
335
- return _jcall (metaclass (T), jmethodId, JNI. NewObjectA, JavaObject{T}, argtypes, args... )
335
+ return _jnicall (metaclass (T), jmethodId, JNI. NewObjectA, JavaObject{T}, argtypes, args... )
336
336
end
337
337
338
+ _jcallable (typ:: Type{JavaObject{T}} ) where T = metaclass (T)
339
+ _jcallable (obj:: JavaObject ) = obj
340
+
338
341
# Call static methods
339
- function jcall (typ:: Type{JavaObject{T}} , method:: AbstractString , rettype:: Type , argtypes:: Tuple = (),
340
- args... ) where T
342
+ function jcall (ref, method:: AbstractString , rettype:: Type , argtypes:: Tuple = (), args... )
341
343
assertroottask_or_goodenv () && assertloaded ()
342
- sig = method_signature (rettype, argtypes... )
343
- jmethodId = JNI. GetStaticMethodID (Ptr (metaclass (T)), String (method), sig)
344
+ jmethodId = get_method_id (ref, method, rettype, argtypes)
344
345
jmethodId== C_NULL && geterror (true )
345
- _jcall (metaclass (T ), jmethodId, C_NULL , rettype, argtypes, args... )
346
+ _jcall (_jcallable (ref ), jmethodId, rettype, argtypes, args... )
346
347
end
347
348
348
- function jcall (typ:: Type{JavaObject{T}} , method:: JMethod , args... ) where T
349
- assertroottask_or_goodenv () && assertloaded ()
350
- jmethodId = JNI. FromReflectedMethod (method)
351
- rettype = jimport (getreturntype (method))
352
- argtypes = Tuple (jimport .(getparametertypes (method)))
353
- jmethodId== C_NULL && geterror (true )
354
- _jcall (metaclass (T), jmethodId, C_NULL , rettype, argtypes, args... )
349
+ function get_method_id (typ:: Type{JavaObject{T}} , method:: AbstractString , rettype:: Type , argtypes:: Tuple ) where T
350
+ sig = method_signature (rettype, argtypes... )
351
+ JNI. GetStaticMethodID (Ptr (metaclass (T)), String (method), sig)
355
352
end
356
353
357
- # Call instance methods
358
- function jcall (obj:: JavaObject , method:: AbstractString , rettype:: Type , argtypes:: Tuple = (), args... )
359
- assertroottask_or_goodenv () && assertloaded ()
354
+ function get_method_id (obj:: JavaObject , method:: AbstractString , rettype:: Type , argtypes:: Tuple )
355
+ sig = method_signature (rettype, argtypes... )
356
+ JNI. GetMethodID (Ptr (metaclass (obj)), String (method), sig)
357
+ end
358
+
359
+ function get_method_id (obj:: JavaObject , method:: JMethod )
360
360
sig = method_signature (rettype, argtypes... )
361
- jmethodId = JNI. GetMethodID (Ptr (metaclass (obj)), String (method), sig)
361
+ JNI. FromReflectedMethod (method)
362
+ end
363
+
364
+ function jcall (ref, method:: JMethod , args... ) where T
365
+ jmethodId = JNI. FromReflectedMethod (method)
366
+ rettype = jimport (getreturntype (method))
367
+ argtypes = Tuple (jimport .(getparametertypes (method)))
362
368
jmethodId== C_NULL && geterror (true )
363
- _jcall (obj , jmethodId, C_NULL , rettype, argtypes, args... )
369
+ _jcall (metaclass (T) , jmethodId, rettype, argtypes, args... )
364
370
end
365
371
366
372
function jcall (obj:: JavaObject , method:: JMethod , args... )
367
373
assertroottask_or_goodenv () && assertloaded ()
374
+ isnull (obj) && throw (JavaCallError (" Attempt to call method on Java NULL" ))
368
375
jmethodId = JNI. FromReflectedMethod (method)
369
376
rettype = jimport (getreturntype (method))
370
377
argtypes = Tuple (jimport .(getparametertypes (method)))
371
378
jmethodId== C_NULL && geterror (true )
372
- _jcall (obj, jmethodId, C_NULL , rettype, argtypes, args... )
379
+ _jcall (obj, jmethodId, rettype, argtypes, args... )
373
380
end
374
381
375
382
# JMethod invoke
376
383
(m:: JMethod )(obj, args... ) = jcall (obj, m, args... )
377
384
378
385
379
- function jfield (typ :: Type{JavaObject{T}} , field:: AbstractString , fieldType:: Type ) where T
386
+ function jfield (ref , field, fieldType)
380
387
assertroottask_or_goodenv () && assertloaded ()
381
- jfieldID = JNI . GetStaticFieldID ( Ptr ( metaclass (T)), String ( field), signature ( fieldType) )
388
+ jfieldID = get_field_id (ref, field, fieldType)
382
389
jfieldID== C_NULL && geterror (true )
383
- _jfield (metaclass (T ), jfieldID, fieldType)
390
+ _jfield (_jcallable (ref ), jfieldID, fieldType)
384
391
end
385
392
386
- function jfield (obj:: Type{JavaObject{T}} , field:: JField ) where T
387
- assertroottask_or_goodenv () && assertloaded ()
393
+ function get_field_id (typ:: Type{JavaObject{T}} , field:: AbstractString , fieldType:: Type ) where T
394
+ JNI. GetStaticFieldID (Ptr (metaclass (T)), String (field), signature (fieldType))
395
+ end
396
+
397
+ function get_field_id (obj:: Type{JavaObject{T}} , field:: JField ) where T
388
398
fieldType = jimport (gettype (field))
389
- jfieldID = JNI. FromReflectedField (field)
390
- jfieldID== C_NULL && geterror (true )
391
- _jfield (metaclass (T), jfieldID, fieldType)
399
+ JNI. FromReflectedField (field)
392
400
end
393
401
394
- function jfield (obj:: JavaObject , field:: AbstractString , fieldType:: Type )
395
- assertroottask_or_goodenv () && assertloaded ()
396
- jfieldID = JNI. GetFieldID (Ptr (metaclass (obj)), String (field), signature (fieldType))
397
- jfieldID== C_NULL && geterror (true )
398
- _jfield (obj, jfieldID, fieldType)
402
+ function get_field_id (obj:: JavaObject , field:: AbstractString , fieldType:: Type )
403
+ JNI. GetFieldID (Ptr (metaclass (obj)), String (field), signature (fieldType))
399
404
end
400
405
401
- function jfield (obj:: JavaObject , field:: JField )
402
- assertroottask_or_goodenv () && assertloaded ()
406
+ function get_field_id (obj:: JavaObject , field:: JField )
403
407
fieldType = jimport (gettype (field))
404
- jfieldID = JNI. FromReflectedField (field)
405
- jfieldID== C_NULL && geterror (true )
406
- _jfield (obj, jfieldID, fieldType)
408
+ JNI. FromReflectedField (field)
407
409
end
408
410
409
411
# JField invoke
410
412
(f:: JField )(obj) = jfield (obj, f)
411
413
412
- for (x, y, z) in [(:jboolean , :(JNI. GetBooleanField), :(JNI. GetStaticBooleanField)),
413
- (:jchar , :(JNI. GetCharField), :(JNI. GetStaticCharField)) ,
414
- (:jbyte , :(JNI. GetByteField), :(JNI. GetStaticBypeField)) ,
415
- (:jshort , :(JNI. GetShortField), :(JNI. GetStaticShortField)) ,
416
- (:jint , :(JNI. GetIntField), :(JNI. GetStaticIntField)) ,
417
- (:jlong , :(JNI. GetLongField), :(JNI. GetStaticLongField)) ,
418
- (:jfloat , :(JNI. GetFloatField), :(JNI. GetStaticFloatField)) ,
419
- (:jdouble , :(JNI. GetDoubleField), :(JNI. GetStaticDoubleField)) ]
420
-
421
- m = quote
422
- function _jfield (obj, jfieldID:: Ptr{Nothing} , fieldType:: Type{$(x)} )
423
- callmethod = ifelse ( typeof (obj)<: JavaObject , $ y , $ z )
424
- result = callmethod (Ptr (obj), jfieldID)
425
- result== C_NULL && geterror ()
426
- return convert_result (fieldType, result)
427
- end
428
- end
429
- eval (m)
430
- end
431
-
432
414
function _jfield (obj, jfieldID:: Ptr{Nothing} , fieldType:: Type )
433
- callmethod = ifelse ( typeof (obj)<: JavaObject , JNI. GetObjectField , JNI. GetStaticObjectField )
434
- result = callmethod (Ptr (obj), jfieldID)
415
+ result = _jnifield (obj, jfieldID, fieldType)
435
416
result== C_NULL && geterror ()
436
417
return convert_result (fieldType, result)
437
418
end
438
419
439
- # Generate these methods to satisfy ccall's compile time constant requirement
440
- # _jcall for primitive and Nothing return types
441
- for (x, y, z) in [(:jboolean , :(JNI. CallBooleanMethodA), :(JNI. CallStaticBooleanMethodA)),
442
- (:jchar , :(JNI. CallCharMethodA), :(JNI. CallStaticCharMethodA)) ,
443
- (:jbyte , :(JNI. CallByteMethodA), :(JNI. CallStaticByteMethodA)) ,
444
- (:jshort , :(JNI. CallShortMethodA), :(JNI. CallStaticShortMethodA)) ,
445
- (:jint , :(JNI. CallIntMethodA), :(JNI. CallStaticIntMethodA)) ,
446
- (:jlong , :(JNI. CallLongMethodA), :(JNI. CallStaticLongMethodA)) ,
447
- (:jfloat , :(JNI. CallFloatMethodA), :(JNI. CallStaticFloatMethodA)) ,
448
- (:jdouble , :(JNI. CallDoubleMethodA), :(JNI. CallStaticDoubleMethodA)) ,
449
- (:jvoid , :(JNI. CallVoidMethodA), :(JNI. CallStaticVoidMethodA)) ]
450
- m = quote
451
- function _jcall (obj, jmethodId:: Ptr{Nothing} , callmethod:: Ptr{Nothing} , rettype:: Type{$(x)} ,
452
- argtypes:: Tuple , args... )
453
- if callmethod == C_NULL # !
454
- callmethod = ifelse ( typeof (obj)<: JavaObject , $ y , $ z )
455
- end
456
- @assert callmethod != C_NULL
457
- @assert jmethodId != C_NULL
458
- isnull (obj) && throw (JavaCallError (" Attempt to call method on Java NULL" ))
459
- savedArgs, convertedArgs = convert_args (argtypes, args... )
460
- GC. @preserve savedArgs begin
461
- result = callmethod (Ptr (obj), jmethodId, Array {JNI.jvalue} (jvalue .(convertedArgs)))
462
- end
463
- deleteref .(filter (x-> isa (x,JavaObject),convertedArgs))
464
- result== C_NULL && geterror ()
465
- result == nothing && (return )
466
- return convert_result (rettype, result)
467
- end
468
- end
469
- eval (m)
470
- end
471
-
472
- # _jcall for Object return types
473
- # obj -- receiver - Class pointer or object prointer
474
- # jmethodId -- Java method ID
475
- # callmethod -- the C method pointer to call
476
- function _jcall (obj, jmethodId:: Ptr{Nothing} , callmethod:: Union{Function,Ptr{Nothing}} , rettype:: Type , argtypes:: Tuple ,
477
- args... )
478
- if callmethod == C_NULL
479
- callmethod = ifelse (typeof (obj)<: JavaObject ,
480
- JNI. CallObjectMethodA ,
481
- JNI. CallStaticObjectMethodA)
482
- end
483
- @assert callmethod != C_NULL
484
- @assert jmethodId != C_NULL
485
- isnull (obj) && error (" Attempt to call method on Java NULL" )
420
+ function _jcall (obj, jmethodId, callmethod, rettype, argtypes, args... )
486
421
savedArgs, convertedArgs = convert_args (argtypes, args... )
487
422
GC. @preserve savedArgs begin
488
- result = callmethod ( Ptr ( obj) , jmethodId, Array {JNI. jvalue} ( jvalue .(convertedArgs) ))
423
+ result = _jnicall ( obj, jmethodId, rettype, argtypes, jvalue .(convertedArgs))
489
424
end
490
425
deleteref .(filter (x-> isa (x,JavaObject),convertedArgs))
491
426
result== C_NULL && geterror ()
492
427
return convert_result (rettype, result)
493
428
end
494
429
430
+ # Generate these methods to satisfy ccall's compile time constant requirement
431
+ for (x, name) in [(:Type , " Object" ),
432
+ (:(Type{jboolean}), " Boolean" ),
433
+ (:(Type{jchar}), " Char" ),
434
+ (:(Type{jbyte}), " Byte" ),
435
+ (:(Type{jshort}), " Short" ),
436
+ (:(Type{jint}), " Int" ),
437
+ (:(Type{jlong}), " Long" ),
438
+ (:(Type{jfloat}), " Float" ),
439
+ (:(Type{jdouble}), " Double" ),
440
+ (:(Type{jvoid}), " Void" )]
441
+ for (t, cstr, fstr) in [(:JavaObject , " Call$(name) MethodA" , " Get$(name) Field" ),
442
+ (:JavaMetaClass , " CallStatic$(name) MethodA" , " GetStatic$(name) Field" )]
443
+ callmethod = :(JNI.$ (Symbol (cstr)))
444
+ fieldmethod = :(JNI.$ (Symbol (fstr)))
445
+ m = quote
446
+ function _jnicall (obj:: T , jmethodId:: Ptr{Nothing} , rettype:: $x ,
447
+ argtypes:: Tuple , args) where T <: $t
448
+ $ callmethod (Ptr (obj), jmethodId, Array {JNI.jvalue} (args))
449
+ end
450
+ function _jnifield (obj:: T , jfieldID:: Ptr{Nothing} , fieldType:: $x ) where T <: $t
451
+ $ fieldmethod (Ptr (obj), jfieldID)
452
+ end
453
+ end
454
+ eval (m)
455
+ end
456
+ end
495
457
496
458
global const _jmc_cache = [ Dict {Symbol, JavaMetaClass} () ]
497
459
@@ -557,33 +519,17 @@ function method_signature(rettype, argtypes...)
557
519
return String (take! (s))
558
520
end
559
521
560
-
561
522
# get the JNI signature string for a given type
562
- function signature (arg:: Type )
563
- if arg === jboolean
564
- return " Z"
565
- elseif arg === jbyte
566
- return " B"
567
- elseif arg === jchar
568
- return " C"
569
- elseif arg === jshort
570
- return " S"
571
- elseif arg === jint
572
- return " I"
573
- elseif arg === jlong
574
- return " J"
575
- elseif arg === jfloat
576
- return " F"
577
- elseif arg === jdouble
578
- return " D"
579
- elseif arg === jvoid
580
- return " V"
581
- elseif arg <: Array
582
- dims = " [" ^ ndims (arg)
583
- return string (dims, signature (eltype (arg)))
584
- end
585
- end
586
-
523
+ signature (:: Type{jboolean} ) = " Z"
524
+ signature (:: Type{jbyte} ) = " B"
525
+ signature (:: Type{jchar} ) = " C"
526
+ signature (:: Type{jshort} ) = " S"
527
+ signature (:: Type{jint} ) = " I"
528
+ signature (:: Type{jlong} ) = " J"
529
+ signature (:: Type{jfloat} ) = " F"
530
+ signature (:: Type{jdouble} ) = " D"
531
+ signature (:: Type{jvoid} ) = " V"
532
+ signature (:: Type{Array{T,N}} ) where {T,N} = string (" [" ^ N, signature (T))
587
533
signature (arg:: Type{JavaObject{T}} ) where {T} = string (" L" , javaclassname (T), " ;" )
588
534
signature (arg:: Type{JavaObject{T}} ) where {T <: AbstractVector } = JavaCall. javaclassname (T)
589
535
0 commit comments