00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #define JPL_C_LIB_VERSION "3.1.4-alpha"
00048 #define JPL_C_LIB_VERSION_MAJOR 3
00049 #define JPL_C_LIB_VERSION_MINOR 1
00050 #define JPL_C_LIB_VERSION_PATCH 4
00051 #define JPL_C_LIB_VERSION_STATUS "alpha"
00052
00053
00054 #define DEBUG_LEVEL 3
00055 #define DEBUG(n, g) ( n >= DEBUG_LEVEL ? g : (void)0 )
00056
00057
00058 #define JPL_CACHE_TYPE_OF_REF FALSE
00059
00060
00061
00062 #ifdef __WINDOWS__
00063
00064
00065 #include <windows.h>
00066 #define SIZEOF_WCHAR_T 2
00067 #define SIZEOF_LONG 4
00068 #define SIZEOF_LONG_LONG 8
00069 #ifdef WIN64
00070 #define SIZEOF_VOIDP 8
00071 #else
00072 #define SIZEOF_VOIDP 4
00073 #endif
00074 #endif
00075
00076
00077 #include <SWI-Prolog.h>
00078 #include <SWI-Stream.h>
00079
00080
00081 #include <jni.h>
00082
00083
00084 #include <stdlib.h>
00085 #include <ctype.h>
00086 #include <errno.h>
00087 #include <string.h>
00088
00089
00090 #include <pthread.h>
00091 #include <semaphore.h>
00092
00093 #include <limits.h>
00094
00095
00096
00097
00098 #define JNI_MIN_JCHAR 0
00099 #define JNI_MAX_JCHAR 65535
00100
00101 #define JNI_MIN_JBYTE -128
00102 #define JNI_MAX_JBYTE 127
00103
00104 #define JNI_MIN_JSHORT -32768
00105 #define JNI_MAX_JSHORT 32767
00106
00107
00108 #define JNI_XPUT_VOID 0
00109 #define JNI_XPUT_BOOLEAN 1
00110 #define JNI_XPUT_BYTE 2
00111 #define JNI_XPUT_CHAR 3
00112 #define JNI_XPUT_SHORT 4
00113 #define JNI_XPUT_INT 5
00114 #define JNI_XPUT_LONG 6
00115 #define JNI_XPUT_FLOAT 7
00116 #define JNI_XPUT_DOUBLE 8
00117 #define JNI_XPUT_FLOAT_TO_DOUBLE 9
00118 #define JNI_XPUT_LONG_TO_FLOAT 10
00119 #define JNI_XPUT_LONG_TO_DOUBLE 11
00120 #define JNI_XPUT_REF 12
00121 #define JNI_XPUT_ATOM 13
00122 #define JNI_XPUT_JVALUEP 14
00123 #define JNI_XPUT_JVALUE 15
00124
00125
00126
00127
00128 #define JNI_HR_LOAD_FACTOR 0.75
00129
00130
00131 #define JNI_HR_ADD_FAIL -1
00132 #define JNI_HR_ADD_NEW 0
00133 #define JNI_HR_ADD_OLD 1
00134
00135
00136
00137
00138
00139 #define JPL_INIT_RAW 101
00140 #define JPL_INIT_PVM_MAYBE 102
00141 #define JPL_INIT_OK 103
00142 #define JPL_INIT_JPL_FAILED 104
00143 #define JPL_INIT_PVM_FAILED 105
00144
00145 #define JPL_MAX_POOL_ENGINES 10
00146 #define JPL_INITIAL_POOL_ENGINES 1
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 #define JNI_term_to_jboolean(T,JB) \
00157 ( PL_get_functor((T),&fn) \
00158 && fn==JNI_functor_at_1 \
00159 ? ( ( a1=PL_new_term_ref(), \
00160 PL_get_arg(1,(T),a1) \
00161 ) \
00162 && PL_get_atom(a1,&a) \
00163 ? ( a==JNI_atom_false \
00164 ? ( (JB)=0, TRUE) \
00165 : ( a==JNI_atom_true \
00166 ? ( (JB)=1, TRUE) \
00167 : FALSE \
00168 ) \
00169 ) \
00170 : FALSE \
00171 ) \
00172 : FALSE \
00173 )
00174
00175 #define JNI_term_to_jchar(T,J) \
00176 ( PL_get_integer((T),&i) \
00177 && i >= JNI_MIN_JCHAR \
00178 && i <= JNI_MAX_JCHAR \
00179 && ( (J)=(jchar)i, TRUE) \
00180 )
00181
00182 #define JNI_term_to_jbyte(T,J) \
00183 ( PL_get_integer((T),&i) \
00184 && i >= JNI_MIN_JBYTE \
00185 && i <= JNI_MAX_JBYTE \
00186 && ( (J)=(jbyte)i, TRUE) \
00187 )
00188
00189 #define JNI_term_to_jshort(T,J) \
00190 ( PL_get_integer((T),&i) \
00191 && i >= JNI_MIN_JSHORT \
00192 && i <= JNI_MAX_JSHORT \
00193 && ( (J)=(jshort)i, TRUE) \
00194 )
00195
00196
00197
00198 #define JNI_term_to_jint(T,J) \
00199 ( PL_get_integer((T),&i) \
00200 && ((J)=i, TRUE) \
00201 )
00202
00203 #define JNI_term_to_non_neg_jint(T,J) \
00204 ( PL_get_int64((T),&i) \
00205 && i >= 0 \
00206 && ( (J)=(jint)i, TRUE) \
00207 )
00208
00209 #define JNI_term_to_jlong(T,J) \
00210 ( PL_get_int64((T),&i64) \
00211 && ( (J)=(jlong)i64, TRUE) \
00212 )
00213
00214 #define JNI_term_to_jfloat(T,J) \
00215 ( PL_get_float((T),&d) \
00216 ? ( (J)=(jfloat)d, TRUE) \
00217 : ( PL_get_int64((T),&i64) \
00218 && ( (J)=(jfloat)i64, TRUE) \
00219 ) \
00220 )
00221
00222 #define JNI_term_to_jdouble(T,J) \
00223 ( PL_get_float((T),&(J)) \
00224 ? TRUE \
00225 : ( PL_get_int64((T),&i64) \
00226 && ( (J)=(jdouble)i64, TRUE) \
00227 ) \
00228 )
00229
00230 #define JNI_term_to_jfieldID(T,J) \
00231 ( PL_get_functor((T),&fn) \
00232 && fn==JNI_functor_jfieldID_1 \
00233 && ( a1=PL_new_term_ref(), \
00234 PL_get_arg(1,(T),a1) \
00235 ) \
00236 && PL_get_pointer(a1,(void**)&(J)) \
00237 )
00238
00239 #define JNI_term_to_jmethodID(T,J) \
00240 ( PL_get_functor((T),&fn) \
00241 && fn==JNI_functor_jmethodID_1 \
00242 && ( a1=PL_new_term_ref(), \
00243 PL_get_arg(1,(T),a1) \
00244 ) \
00245 && PL_get_pointer(a1,(void**)&(J)) \
00246 )
00247
00248
00249
00250
00251
00252
00253
00254 #define JNI_term_to_ref(T,J) \
00255 ( PL_get_atom((T),&a) \
00256 ? jni_atom_to_String(env,a,(jobject*)&(J)) \
00257 : PL_get_functor((T),&fn) \
00258 && fn==JNI_functor_at_1 \
00259 && ( a1=PL_new_term_ref(), \
00260 PL_get_arg(1,(T),a1) \
00261 ) \
00262 && PL_get_atom(a1,&a) \
00263 && ( a==JNI_atom_null \
00264 ? ( (J)=0, TRUE) \
00265 : jni_tag_to_iref(a,(pointer*)&(J)) \
00266 ) \
00267 )
00268
00269
00270
00271
00272
00273
00274
00275 #define JNI_term_to_jobject(T,J) \
00276 ( JNI_term_to_ref(T,J) \
00277 && (J) != 0 \
00278 )
00279
00280
00281
00282
00283 #define JNI_term_to_jclass(T,J) JNI_term_to_jobject(T,J)
00284
00285 #define JNI_term_to_throwable_jclass(T,J) JNI_term_to_jobject(T,J)
00286
00287 #define JNI_term_to_non_array_jclass(T,J) JNI_term_to_jobject(T,J)
00288
00289 #define JNI_term_to_throwable_jobject(T,J) JNI_term_to_jobject(T,J)
00290
00291 #define JNI_term_to_jstring(T,J) JNI_term_to_jobject(T,J)
00292
00293 #define JNI_term_to_jarray(T,J) JNI_term_to_jobject(T,J)
00294
00295 #define JNI_term_to_object_jarray(T,J) JNI_term_to_jobject(T,J)
00296
00297 #define JNI_term_to_boolean_jarray(T,J) JNI_term_to_jobject(T,J)
00298
00299 #define JNI_term_to_byte_jarray(T,J) JNI_term_to_jobject(T,J)
00300
00301 #define JNI_term_to_char_jarray(T,J) JNI_term_to_jobject(T,J)
00302
00303 #define JNI_term_to_short_jarray(T,J) JNI_term_to_jobject(T,J)
00304
00305 #define JNI_term_to_int_jarray(T,J) JNI_term_to_jobject(T,J)
00306
00307 #define JNI_term_to_long_jarray(T,J) JNI_term_to_jobject(T,J)
00308
00309 #define JNI_term_to_float_jarray(T,J) JNI_term_to_jobject(T,J)
00310
00311 #define JNI_term_to_double_jarray(T,J) JNI_term_to_jobject(T,J)
00312
00313 #define JNI_term_to_jbuf(T,J,TP) \
00314 ( PL_get_functor((T),&fn) \
00315 && fn==JNI_functor_jbuf_2 \
00316 && ( a2=PL_new_term_ref(), \
00317 PL_get_arg(2,(T),a2) \
00318 ) \
00319 && PL_get_atom(a2,&a) \
00320 && a==(TP) \
00321 && ( a1=PL_new_term_ref(), \
00322 PL_get_arg(1,(T),a1) \
00323 ) \
00324 && PL_get_pointer(a1,(void**)&(J)) \
00325 )
00326
00327 #define JNI_term_to_charP(T,J) \
00328 PL_get_atom_chars((T),&(J))
00329
00330 #define JNI_term_to_pointer(T,J) \
00331 PL_get_pointer((T),(void**)&(J))
00332
00333
00334
00335
00336 #define JNI_unify_void(T) \
00337 PL_unify_term((T), \
00338 PL_FUNCTOR, JNI_functor_at_1, \
00339 PL_ATOM, JNI_atom_void \
00340 )
00341
00342 #define JNI_unify_false(T) \
00343 PL_unify_term((T), \
00344 PL_FUNCTOR, JNI_functor_at_1, \
00345 PL_ATOM, JNI_atom_false \
00346 )
00347
00348 #define JNI_unify_true(T) \
00349 PL_unify_term((T), \
00350 PL_FUNCTOR, JNI_functor_at_1, \
00351 PL_ATOM, JNI_atom_true \
00352 )
00353
00354 #define JNI_jboolean_to_term(J,T) \
00355 ( (J)==0 \
00356 ? JNI_unify_false((T)) \
00357 : JNI_unify_true((T)) \
00358 )
00359
00360 #define JNI_jchar_to_term(J,T) \
00361 PL_unify_integer((T),(int)(J))
00362
00363 #define JNI_jbyte_to_term(J,T) \
00364 PL_unify_integer((T),(int)(J))
00365
00366 #define JNI_jshort_to_term(J,T) \
00367 PL_unify_integer((T),(int)(J))
00368
00369 #define JNI_jint_to_term(J,T) \
00370 PL_unify_integer((T),(int)(J))
00371
00372 #define JNI_jlong_to_term(J,T) \
00373 PL_unify_int64((T),(int64_t)(J))
00374
00375 #define JNI_jfloat_to_term(J,T) \
00376 PL_unify_float((T),(double)(J))
00377
00378 #define JNI_jdouble_to_term(J,T) \
00379 PL_unify_float((T),(double)(J))
00380
00381
00382
00383
00384
00385 #define JNI_jobject_to_term(J,T) \
00386 ( ( j=(J), j==NULL ) \
00387 ? PL_unify_term((T), \
00388 PL_FUNCTOR, JNI_functor_at_1, \
00389 PL_ATOM, JNI_atom_null \
00390 ) \
00391 : ( (*env)->IsInstanceOf(env,j,str_class) \
00392 ? jni_String_to_atom(env,j,&a) \
00393 && PL_unify_term((T), \
00394 PL_ATOM, a \
00395 ) \
00396 : jni_object_to_iref(env,j,&i) \
00397 && jni_iref_to_tag(i,&a) \
00398 && PL_unify_term((T), \
00399 PL_FUNCTOR, JNI_functor_at_1, \
00400 PL_ATOM, a \
00401 ) \
00402 ) \
00403 )
00404
00405 #define JNI_jfieldID_to_term(J,T) \
00406 PL_unify_term((T), \
00407 PL_FUNCTOR, JNI_functor_jfieldID_1, \
00408 PL_POINTER, (void*)(J) \
00409 )
00410
00411 #define JNI_jmethodID_to_term(J,T) \
00412 PL_unify_term((T), \
00413 PL_FUNCTOR, JNI_functor_jmethodID_1, \
00414 PL_POINTER, (void*)(J) \
00415 )
00416
00417 #define JNI_jbuf_to_term(J,T,TP) \
00418 PL_unify_term((T), \
00419 PL_FUNCTOR, JNI_functor_jbuf_2, \
00420 PL_POINTER, (void*)(J), \
00421 PL_ATOM, (TP) \
00422 )
00423
00424 #define JNI_pointer_to_term(J,T) \
00425 PL_unify_pointer((T),(void*)(J))
00426
00427 #define JNI_charP_to_term(J,T) \
00428 PL_unify_atom_chars((T),(J))
00429
00430
00431
00432
00433 #define jni_ensure_jvm() ( ( jvm != NULL \
00434 || jni_create_default_jvm() \
00435 ) \
00436 && (env=jni_env()) != NULL \
00437 )
00438
00439
00440
00441
00442
00443
00444
00445 #define jpl_ensure_jpl_init(e) ( jpl_status != JPL_INIT_RAW \
00446 || jpl_ensure_jpl_init_1(e) \
00447 )
00448
00449
00450
00451
00452 #define jpl_ensure_pvm_init(e) ( jpl_status == JPL_INIT_OK \
00453 || jpl_ensure_pvm_init_1(e) \
00454 )
00455
00456
00457
00458
00459 typedef struct Hr_Entry HrEntry;
00460
00461 struct Hr_Entry {
00462 jobject obj;
00463 int hash;
00464 HrEntry *next;
00465 };
00466
00467 typedef struct Hr_Table HrTable;
00468
00469 struct Hr_Table {
00470 int count;
00471 int threshold;
00472 int length;
00473 HrEntry **slots;
00474 };
00475
00476 typedef intptr_t pointer;
00477 typedef int bool;
00478
00479
00480
00481
00482 int size[16] = {
00483 0,
00484 sizeof(jboolean),
00485 sizeof(jbyte),
00486 sizeof(jchar),
00487 sizeof(jshort),
00488 sizeof(jint),
00489 sizeof(jlong),
00490 sizeof(jfloat),
00491 sizeof(jdouble),
00492 0,
00493 0,
00494 0,
00495 0,
00496 0,
00497 0,
00498 sizeof(jvalue)
00499 };
00500
00501
00502
00503
00504 static atom_t JNI_atom_false;
00505 static atom_t JNI_atom_true;
00506
00507 static atom_t JNI_atom_boolean;
00508 static atom_t JNI_atom_char;
00509 static atom_t JNI_atom_byte;
00510 static atom_t JNI_atom_short;
00511 static atom_t JNI_atom_int;
00512 static atom_t JNI_atom_long;
00513 static atom_t JNI_atom_float;
00514 static atom_t JNI_atom_double;
00515
00516 static atom_t JNI_atom_null;
00517 static atom_t JNI_atom_void;
00518
00519 static functor_t JNI_functor_at_1;
00520 static functor_t JNI_functor_jbuf_2;
00521 static functor_t JNI_functor_jlong_2;
00522 static functor_t JNI_functor_jfieldID_1;
00523 static functor_t JNI_functor_jmethodID_1;
00524 static functor_t JNI_functor_error_2;
00525 static functor_t JNI_functor_java_exception_1;
00526 static functor_t JNI_functor_jpl_error_1;
00527
00528
00529
00530
00531 static jclass c_class;
00532 static jmethodID c_getName;
00533 static jclass str_class;
00534 static jclass term_class;
00535 static jclass termt_class;
00536
00537 static jclass sys_class;
00538 static jmethodID sys_ihc;
00539 static jmethodID term_getTerm;
00540 static jmethodID term_put;
00541 static jmethodID term_putTerm;
00542
00543
00544
00545
00546 static jclass jString_c;
00547 static jclass jJPLException_c;
00548 static jclass jTermT_c;
00549 static jclass jAtomT_c;
00550 static jclass jFunctorT_c;
00551 static jclass jFidT_c;
00552 static jclass jPredicateT_c;
00553 static jclass jQidT_c;
00554 static jclass jModuleT_c;
00555 static jclass jEngineT_c;
00556
00557 static jclass jLongHolder_c;
00558 static jclass jPointerHolder_c;
00559 static jclass jIntHolder_c;
00560 static jclass jInt64Holder_c;
00561 static jclass jDoubleHolder_c;
00562 static jclass jStringHolder_c;
00563 static jclass jObjectHolder_c;
00564 static jclass jBooleanHolder_c;
00565
00566
00567
00568
00569 static jfieldID jLongHolderValue_f;
00570 static jfieldID jPointerHolderValue_f;
00571 static jfieldID jIntHolderValue_f;
00572 static jfieldID jInt64HolderValue_f;
00573 static jfieldID jDoubleHolderValue_f;
00574 static jfieldID jStringHolderValue_f;
00575 static jfieldID jObjectHolderValue_f;
00576 static jfieldID jBooleanHolderValue_f;
00577
00578
00579
00580
00581 const char *default_args[] = { "pl",
00582 "-g", "true",
00583 "-nosignals",
00584 NULL
00585 };
00586
00587
00588
00589
00590 static JavaVM *jvm = NULL;
00591 static char *jvm_ia[2] = {"-Xrs", NULL};
00592 static char **jvm_dia = jvm_ia;
00593 static char **jvm_aia = NULL;
00594
00595
00596
00597
00598 static HrTable *hr_table = NULL;
00599 static int hr_add_count = 0;
00600 static int hr_old_count = 0;
00601 static int hr_del_count = 0;
00602
00603
00604
00605
00606 static int jpl_status = JPL_INIT_RAW;
00607 static jobject pvm_dia = NULL;
00608 static jobject pvm_aia = NULL;
00609 static PL_engine_t *engines = NULL;
00610 static int engines_allocated = 0;
00611 static pthread_mutex_t engines_mutex = PTHREAD_MUTEX_INITIALIZER;
00612 static pthread_cond_t engines_cond = PTHREAD_COND_INITIALIZER;
00613
00614 static pthread_mutex_t jvm_init_mutex = PTHREAD_MUTEX_INITIALIZER;
00615 static pthread_mutex_t pvm_init_mutex = PTHREAD_MUTEX_INITIALIZER;
00616
00617
00618
00619
00620 JNIEnv*
00621 jni_env()
00622 { JNIEnv *env;
00623
00624 switch( (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_2) )
00625 { case JNI_OK:
00626 return env;
00627 case JNI_EDETACHED:
00628 DEBUG(2, Sdprintf( "[JPL: jni_env() calls AttachCurrentThread]\n"));
00629 return (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL) == 0 ? env : NULL;
00630 default:
00631 return NULL;
00632 }
00633 }
00634
00635
00636 static char *
00637 jpl_c_lib_version()
00638 {
00639 static char v[100];
00640 static char *vp = NULL;
00641
00642 if ( vp != NULL )
00643 {
00644 return vp;
00645 }
00646 sprintf( v, "%d.%d.%d-%s", JPL_C_LIB_VERSION_MAJOR, JPL_C_LIB_VERSION_MINOR, JPL_C_LIB_VERSION_PATCH, JPL_C_LIB_VERSION_STATUS);
00647 vp = v;
00648 return vp;
00649 }
00650
00651
00652 static foreign_t
00653 jpl_c_lib_version_1_plc(
00654 term_t ta
00655 )
00656 {
00657
00658 return PL_unify_atom_chars(ta,jpl_c_lib_version());
00659 }
00660
00661
00662 static foreign_t
00663 jpl_c_lib_version_4_plc(
00664 term_t tmajor,
00665 term_t tminor,
00666 term_t tpatch,
00667 term_t tstatus
00668 )
00669 {
00670
00671 return PL_unify_integer(tmajor,JPL_C_LIB_VERSION_MAJOR)
00672 && PL_unify_integer(tminor,JPL_C_LIB_VERSION_MINOR)
00673 && PL_unify_integer(tpatch,JPL_C_LIB_VERSION_PATCH)
00674 && PL_unify_atom_chars(tstatus,JPL_C_LIB_VERSION_STATUS);
00675 }
00676
00677
00678
00679
00680 static int jni_hr_add(JNIEnv*, jobject, pointer*);
00681 static int jni_hr_del(JNIEnv*, pointer);
00682
00683
00684
00685
00686 static bool
00687 jni_tag_to_iref2(const char *s, pointer *iref)
00688 { if ( s[0] == 'J'
00689 && s[1] == '#'
00690 && isdigit(s[2])
00691 && isdigit(s[3])
00692 && isdigit(s[4])
00693 && isdigit(s[5])
00694 && isdigit(s[6])
00695 && isdigit(s[7])
00696 && isdigit(s[8])
00697 && isdigit(s[9])
00698 && isdigit(s[10])
00699 && isdigit(s[11])
00700 && isdigit(s[12])
00701 && isdigit(s[13])
00702 && isdigit(s[14])
00703 && isdigit(s[15])
00704 && isdigit(s[16])
00705 && isdigit(s[17])
00706 && isdigit(s[18])
00707 && isdigit(s[19])
00708 && isdigit(s[20])
00709 && isdigit(s[21]))
00710 { pointer r;
00711 char *endptr;
00712
00713 r = strtoul(&s[2], &endptr, 10);
00714 if ( endptr == s+22 )
00715 { *iref = r;
00716 return 1;
00717 }
00718 }
00719
00720 return 0;
00721 }
00722
00723
00724 static bool
00725 jni_tag_to_iref1(
00726 const char *s,
00727 pointer *iref
00728 )
00729 {
00730
00731 if (strlen(s) == 22)
00732 {
00733 return jni_tag_to_iref2(s,iref);
00734 }
00735 else
00736 {
00737 return 0;
00738 }
00739 }
00740
00741
00742
00743 static bool
00744 jni_tag_to_iref(
00745 atom_t a,
00746 pointer *iref
00747 )
00748 {
00749
00750 return jni_tag_to_iref1(PL_atom_chars(a), iref);
00751 }
00752
00753
00754 #if SIZEOF_LONG == SIZEOF_VOIDP
00755 #define IREF_FMT "J#%020lu"
00756 #define IREF_INTTYPE unsigned long
00757 #elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
00758 #define IREF_FMT "J#%020llu"
00759 #define IREF_INTTYPE unsigned long long
00760 #else
00761 #error "Cannot determine format for irefs"
00762 #endif
00763
00764 static bool
00765 jni_iref_to_tag(
00766 pointer iref,
00767 atom_t *a
00768 )
00769 {
00770 char abuf[23];
00771
00772 sprintf( abuf, IREF_FMT, (IREF_INTTYPE)iref);
00773 *a = PL_new_atom(abuf);
00774 PL_unregister_atom(*a);
00775 return TRUE;
00776 }
00777
00778
00779 static bool
00780 jni_object_to_iref(
00781 JNIEnv *env,
00782 jobject obj,
00783 pointer *iref
00784 )
00785 {
00786 int r;
00787
00788 if ( (r=jni_hr_add(env, obj, iref)) == JNI_HR_ADD_NEW )
00789 {
00790 hr_add_count++;
00791 return TRUE;
00792 }
00793 else
00794 if ( r == JNI_HR_ADD_OLD )
00795 {
00796 hr_old_count++;
00797 return TRUE;
00798 }
00799 else
00800 {
00801 return FALSE;
00802 }
00803 }
00804
00805
00806
00807 static bool
00808 jni_tidy_iref_type_cache(
00809 pointer iref
00810 )
00811 {
00812 term_t goal;
00813
00814 if ( JPL_CACHE_TYPE_OF_REF )
00815 {
00816 goal = PL_new_term_ref();
00817 PL_unify_term( goal,
00818 PL_FUNCTOR, PL_new_functor(PL_new_atom("jpl_tidy_iref_type_cache"),1),
00819 PL_INT, iref
00820 );
00821 return PL_call(
00822 goal,
00823 PL_new_module(PL_new_atom("jpl"))
00824 );
00825 }
00826 else
00827 {
00828 return TRUE;
00829 }
00830 }
00831
00832
00833
00834 static bool
00835 jni_free_iref(
00836 JNIEnv *env,
00837 pointer iref
00838 )
00839 {
00840
00841 if ( jni_hr_del(env,iref) )
00842 {
00843 if ( !jni_tidy_iref_type_cache(iref) )
00844 {
00845 DEBUG(0, Sdprintf( "[JPL: jni_tidy_iref_type_cache(%u) failed]\n", iref));
00846 }
00847 hr_del_count++;
00848 return TRUE;
00849 }
00850 else
00851 {
00852 return FALSE;
00853 }
00854 }
00855
00856
00857
00858
00859 static bool
00860 jni_String_to_atom(
00861 JNIEnv *env,
00862 jobject s,
00863 atom_t *a
00864 )
00865 {
00866 jsize len = (*env)->GetStringLength(env,s);
00867 const jchar *jcp = (*env)->GetStringChars(env,s,NULL);
00868
00869 if ( s == NULL )
00870 {
00871 return FALSE;
00872 }
00873 #if SIZEOF_WCHAR_T == 2
00874 {
00875 *a = PL_new_atom_wchars(len,jcp);
00876 }
00877 #else
00878 {
00879 pl_wchar_t *wp;
00880 jsize i;
00881
00882 if ( (wp=(pl_wchar_t*)malloc(sizeof(pl_wchar_t)*len)) == NULL) {
00883 (*env)->ReleaseStringChars(env,s,jcp);
00884 return FALSE;
00885 }
00886 for ( i=0 ; i<len ; i++ )
00887 {
00888 wp[i] = (pl_wchar_t)jcp[i];
00889 }
00890 *a = PL_new_atom_wchars(len,wp);
00891 free( wp);
00892 }
00893 #endif
00894 (*env)->ReleaseStringChars(env,s,jcp);
00895 return TRUE;
00896 }
00897
00898
00899
00900 static bool
00901 jni_atom_to_String(
00902 JNIEnv *env,
00903 atom_t a,
00904 jobject *s
00905 )
00906 {
00907 size_t len;
00908 pl_wchar_t *wp;
00909 jchar *jcp;
00910 unsigned char *cp;
00911 unsigned int i;
00912
00913 if ( (cp=(unsigned char*)PL_atom_nchars(a,&len)) != NULL )
00914 {
00915 jcp = (jchar*)malloc(sizeof(jchar)*len);
00916 for ( i=0 ; i<len ; i++ )
00917 {
00918 jcp[i] = (jchar)cp[i];
00919 }
00920 *s = (*env)->NewString(env,jcp,(jsize)len);
00921 free(jcp);
00922 return TRUE;
00923 }
00924 else if ( (wp=(pl_wchar_t*)PL_atom_wchars(a,&len)) != NULL )
00925 {
00926 #if SIZEOF_WCHAR_T == 2
00927 {
00928 *s = (*env)->NewString(env,wp,(jsize)len);
00929 }
00930 #else
00931 {
00932 jcp = (jchar*)malloc(sizeof(jchar)*len);
00933 for ( i=0 ; i<len ; i++ )
00934 {
00935 jcp[i] = (jchar)wp[i];
00936 }
00937 *s = (*env)->NewString(env,jcp,len);
00938 free(jcp);
00939 }
00940 #endif
00941 return TRUE;
00942 }
00943 else
00944 {
00945 return FALSE;
00946 }
00947 }
00948
00949
00950
00951 static bool
00952 jni_string_to_String(
00953 JNIEnv *env,
00954 term_t t,
00955 jobject *s
00956 )
00957 {
00958 size_t len;
00959 pl_wchar_t *wp;
00960 jchar *jcp;
00961 char *cp;
00962 unsigned int i;
00963
00964 if ( PL_get_nchars(t,&len,&cp,CVT_ATOM) )
00965 {
00966 jcp = (jchar*)malloc(sizeof(jchar)*len);
00967 for ( i=0 ; i<len ; i++ )
00968 {
00969 jcp[i] = (jchar)cp[i];
00970 }
00971 *s = (*env)->NewString(env,jcp,(jsize)len);
00972 free(jcp);
00973 return TRUE;
00974 }
00975 else if ( PL_get_wchars(t,&len,&wp,CVT_STRING) )
00976 {
00977 #if SIZEOF_WCHAR_T == 2
00978 {
00979 *s = (*env)->NewString(env,wp,(jsize)len);
00980 }
00981 #else
00982 {
00983 jcp = (jchar*)malloc(sizeof(jchar)*len);
00984 for ( i=0 ; i<len ; i++ )
00985 {
00986 jcp[i] = (jchar)wp[i];
00987 }
00988 *s = (*env)->NewString(env,jcp,len);
00989 free(jcp);
00990 }
00991 #endif
00992 return TRUE;
00993 }
00994 else
00995 {
00996 return FALSE;
00997 }
00998 }
00999
01000
01001
01002
01003
01004 static foreign_t
01005 jni_tag_to_iref_plc(
01006 term_t tt,
01007 term_t ti
01008 )
01009 {
01010 atom_t a;
01011 pointer iref;
01012
01013 return PL_get_atom(tt,&a)
01014 && jni_tag_to_iref(a,&iref)
01015 && PL_unify_integer(ti,iref);
01016 }
01017
01018
01019
01020
01021
01022 static bool
01023 jni_atom_freed(
01024 atom_t a
01025 )
01026 {
01027 const char *cp = PL_atom_chars(a);
01028 pointer iref;
01029 char cs[23];
01030 JNIEnv *env;
01031
01032 if ((env = jni_env()) == NULL)
01033 return TRUE;
01034 if ( jni_tag_to_iref( a, &iref) )
01035 {
01036 sprintf( cs, IREF_FMT, (IREF_INTTYPE)iref);
01037 if ( strcmp(cp,cs) != 0 )
01038 {
01039 DEBUG(0, Sdprintf( "[JPL: garbage-collected tag '%s'=%u is bogus (not canonical)]\n", cp, iref));
01040 }
01041 else
01042 if ( !jni_free_iref(env,iref) )
01043 {
01044 DEBUG(0, Sdprintf( "[JPL: garbage-collected tag '%s' is bogus (not in HashedRefs)]\n", cp));
01045 }
01046 }
01047 else
01048 {
01049 }
01050 return TRUE;
01051 }
01052
01053
01054
01055
01056 static foreign_t
01057 jni_hr_info_plc(
01058 term_t t1,
01059 term_t t2,
01060 term_t t3,
01061 term_t t4
01062 )
01063 {
01064 return PL_unify_integer(t1,(hr_table==NULL?0:hr_table->count))
01065 && PL_unify_integer(t2,hr_add_count)
01066 && PL_unify_integer(t3,hr_old_count)
01067 && PL_unify_integer(t4,hr_del_count);
01068 }
01069
01070
01071
01072 static bool
01073 jni_hr_table_slot(
01074 term_t t2,
01075 HrEntry *slot
01076 )
01077 {
01078 term_t tp = PL_new_term_ref();
01079
01080 if ( slot == NULL )
01081 {
01082 return PL_unify_nil(t2);
01083 }
01084 else
01085 {
01086 return PL_unify_list(t2,tp,t2)
01087 && PL_unify_term(tp,
01088 PL_FUNCTOR, PL_new_functor(PL_new_atom("-"),2),
01089 PL_INT, slot->hash,
01090 PL_LONG, slot->obj
01091 )
01092 && jni_hr_table_slot(t2,slot->next)
01093 ;
01094 }
01095 }
01096
01097
01098
01099 static foreign_t
01100 jni_hr_table_plc(
01101 term_t t
01102 )
01103 {
01104 term_t t1 = PL_copy_term_ref(t);
01105 term_t t2 = PL_new_term_ref();
01106 int i;
01107
01108 for ( i=0 ; i<hr_table->length ; i++ )
01109 {
01110 if ( !PL_unify_list(t1,t2,t1) || !jni_hr_table_slot(t2,hr_table->slots[i]) )
01111 {
01112 return FALSE;
01113 }
01114 }
01115 return PL_unify_nil(t1);
01116 }
01117
01118
01119
01120 static bool
01121 jni_hr_create(
01122 int length
01123 )
01124 {
01125 int i;
01126
01127 if ( hr_table != NULL )
01128 {
01129 return FALSE;
01130 }
01131 if ( length <= 0 )
01132 {
01133 return FALSE;
01134 }
01135 if ( (hr_table=(HrTable*)malloc(sizeof(HrTable))) == NULL )
01136 {
01137 return FALSE;
01138 }
01139 hr_table->length = length;
01140 hr_table->threshold = (int)(hr_table->length*JNI_HR_LOAD_FACTOR);
01141 if ( (hr_table->slots=(HrEntry**)malloc(length*sizeof(HrEntry*))) == NULL )
01142 {
01143 return FALSE;
01144 }
01145 for ( i=0 ; i<hr_table->length ; i++ )
01146 {
01147 hr_table->slots[i] = NULL;
01148 }
01149 hr_table->count = 0;
01150 return TRUE;
01151 }
01152
01153
01154
01155 static bool
01156 jni_hr_create_default()
01157 {
01158
01159 return jni_hr_create( 101);
01160 }
01161
01162
01163
01164 static void
01165 jni_hr_free_chain_entries(
01166 HrEntry *ep
01167 )
01168 {
01169
01170 if ( ep != NULL )
01171 {
01172 jni_hr_free_chain_entries( ep->next);
01173 free( ep);
01174 }
01175 }
01176
01177
01178
01179 static void
01180 jni_hr_free_table_chains(
01181 HrTable *t
01182 )
01183 {
01184 int index;
01185
01186 for ( index=0 ; index<(t->length) ; index++ )
01187 {
01188 jni_hr_free_chain_entries( t->slots[index]);
01189 t->slots[index] = NULL;
01190 }
01191 t->count = 0;
01192 }
01193
01194
01195
01196 static bool
01197 jni_hr_free_table(
01198 HrTable *t
01199 )
01200 {
01201
01202 if ( t == NULL )
01203 {
01204 return FALSE;
01205 }
01206 else
01207 {
01208 jni_hr_free_table_chains( t);
01209 free( t);
01210 return TRUE;
01211 }
01212 }
01213
01214
01215
01216 static bool
01217 jni_hr_rehash()
01218 {
01219 HrTable *t0;
01220 int i;
01221 HrEntry *ep1;
01222 HrEntry *ep2;
01223 int index;
01224
01225 t0 = hr_table;
01226 hr_table = NULL;
01227 if ( !jni_hr_create(2*t0->length+1) )
01228 {
01229 hr_table = t0;
01230 return FALSE;
01231 }
01232 for ( i=0 ; i<t0->length ; i++ )
01233 {
01234 for ( ep1=t0->slots[i] ; ep1!=NULL ; )
01235 {
01236 ep2 = ep1;
01237 ep1 = ep1->next;
01238 index = (ep2->hash & 0x7fffffff) % hr_table->length;
01239 ep2->next = hr_table->slots[index];
01240 hr_table->slots[index] = ep2;
01241 }
01242 t0->slots[i] = NULL;
01243 }
01244 hr_table->count = t0->count;
01245 jni_hr_free_table( t0);
01246 return TRUE;
01247 }
01248
01249
01250 static bool
01251 jni_hr_hash(
01252 JNIEnv *env,
01253 jobject obj,
01254 int *hash
01255 )
01256 {
01257 jobject e;
01258
01259 *hash = (*env)->CallStaticIntMethod(env,sys_class,sys_ihc,obj,obj);
01260 return (e=(*env)->ExceptionOccurred(env))==NULL;
01261 }
01262
01263
01264
01265
01266
01267
01268
01269 static int
01270 jni_hr_add(
01271 JNIEnv *env,
01272 jobject lref,
01273 pointer *iref
01274 )
01275 {
01276 int hash;
01277 int index;
01278 HrEntry *ep;
01279 jobject gref;
01280
01281 if ( hr_table==NULL && !jni_hr_create_default() )
01282 {
01283 return JNI_HR_ADD_FAIL;
01284 }
01285 if ( !jni_hr_hash(env,lref,&hash) )
01286 {
01287 return JNI_HR_ADD_FAIL;
01288 }
01289 index = (hash & 0x7fffffff) % hr_table->length;
01290 for ( ep=hr_table->slots[index] ; ep!=NULL ; ep=ep->next )
01291 {
01292 if ( ep->hash==hash )
01293 {
01294 if ( (*env)->IsSameObject(env,ep->obj,lref) )
01295 {
01296 (*env)->DeleteLocalRef(env,lref);
01297 *iref = (pointer)ep->obj;
01298 return JNI_HR_ADD_OLD;
01299 }
01300 }
01301 }
01302 if ( hr_table->count >= hr_table->threshold )
01303 {
01304 (void)jni_hr_rehash();
01305 return jni_hr_add(env,lref,iref);
01306 }
01307
01308 if ( (gref=(*env)->NewGlobalRef(env,lref)) == NULL )
01309 {
01310 return JNI_HR_ADD_FAIL;
01311 }
01312 (*env)->DeleteLocalRef(env,lref);
01313 ep = (HrEntry*)malloc(sizeof(HrEntry));
01314 ep->hash = hash;
01315 ep->obj = gref;
01316 ep->next = hr_table->slots[index];
01317 hr_table->slots[index] = ep;
01318 hr_table->count++;
01319 *iref = (pointer)gref;
01320 return JNI_HR_ADD_NEW;
01321 }
01322
01323
01324
01325
01326
01327 static bool
01328 jni_hr_del(
01329 JNIEnv *env,
01330 pointer iref
01331 )
01332 {
01333 int index;
01334 HrEntry *ep;
01335 HrEntry **epp;
01336
01337 DEBUG(1, Sdprintf( "[removing possible object reference %u]\n", iref));
01338 for ( index=0 ; index<hr_table->length ; index++ )
01339 {
01340 for ( epp=&(hr_table->slots[index]), ep=*epp ; ep!=NULL ; epp=&(ep->next), ep=*epp )
01341 {
01342 if ( (pointer)(ep->obj) == iref )
01343 {
01344 (*env)->DeleteGlobalRef( env, ep->obj);
01345 *epp = ep->next;
01346 free( ep);
01347 hr_table->count--;
01348 DEBUG(1, Sdprintf( "[found & removed hashtable entry for object reference %u]\n", iref));
01349 return TRUE;
01350 }
01351 }
01352 }
01353 DEBUG(1, Sdprintf("[JPL: failed to find hashtable entry for (presumably bogus) object reference %u]\n", iref));
01354 return FALSE;
01355 }
01356
01357
01358
01359
01360
01361 static int
01362 jni_init()
01363 {
01364 jclass lref;
01365 JNIEnv *env = jni_env();
01366
01367 if (env == NULL)
01368 return -8;
01369
01370
01371 JNI_atom_false = PL_new_atom( "false");
01372 JNI_atom_true = PL_new_atom( "true");
01373
01374 JNI_atom_boolean = PL_new_atom( "boolean");
01375 JNI_atom_char = PL_new_atom( "char");
01376 JNI_atom_byte = PL_new_atom( "byte");
01377 JNI_atom_short = PL_new_atom( "short");
01378 JNI_atom_int = PL_new_atom( "int");
01379 JNI_atom_long = PL_new_atom( "long");
01380 JNI_atom_float = PL_new_atom( "float");
01381 JNI_atom_double = PL_new_atom( "double");
01382
01383 JNI_atom_null = PL_new_atom( "null");
01384 JNI_atom_void = PL_new_atom( "void");
01385
01386 JNI_functor_at_1 = PL_new_functor( PL_new_atom("@"), 1);
01387 JNI_functor_jbuf_2 = PL_new_functor( PL_new_atom("jbuf"), 2);
01388 JNI_functor_jlong_2 = PL_new_functor( PL_new_atom("jlong"), 2);
01389 JNI_functor_jfieldID_1 = PL_new_functor( PL_new_atom("jfieldID"), 1);
01390 JNI_functor_jmethodID_1 = PL_new_functor( PL_new_atom("jmethodID"), 1);
01391
01392 JNI_functor_error_2 = PL_new_functor(PL_new_atom("error"), 2);
01393 JNI_functor_java_exception_1 = PL_new_functor( PL_new_atom("java_exception"), 1);
01394 JNI_functor_jpl_error_1 = PL_new_functor( PL_new_atom("jpl_error"), 1);
01395
01396 (void)PL_agc_hook( jni_atom_freed);
01397
01398
01399 return ( (lref=(*env)->FindClass(env,"java/lang/Class")) != NULL
01400 && (c_class=(*env)->NewGlobalRef(env,lref)) != NULL
01401 && ( (*env)->DeleteLocalRef(env,lref), TRUE)
01402
01403 && (lref=(*env)->FindClass(env,"java/lang/String")) != NULL
01404 && (str_class=(*env)->NewGlobalRef(env,lref)) != NULL
01405 && ( (*env)->DeleteLocalRef(env,lref), TRUE)
01406 && (c_getName=(*env)->GetMethodID(env,c_class,"getName","()Ljava/lang/String;")) != NULL
01407
01408 && (lref=(*env)->FindClass(env,"java/lang/System")) != NULL
01409 && (sys_class=(*env)->NewGlobalRef(env,lref)) != NULL
01410 && ( (*env)->DeleteLocalRef(env,lref), TRUE)
01411 && (sys_ihc=(*env)->GetStaticMethodID(env,sys_class,"identityHashCode","(Ljava/lang/Object;)I")) != NULL
01412
01413 && (lref=(*env)->FindClass(env,"jpl/Term")) != NULL
01414 && (term_class=(*env)->NewGlobalRef(env,lref)) != NULL
01415 && ( (*env)->DeleteLocalRef(env,lref), TRUE)
01416 && (term_getTerm=(*env)->GetStaticMethodID(env,term_class,"getTerm","(Ljpl/fli/term_t;)Ljpl/Term;")) != NULL
01417 && (term_put=(*env)->GetMethodID(env,term_class,"put","(Ljpl/fli/term_t;)V")) != NULL
01418 && (term_putTerm=(*env)->GetStaticMethodID(env,term_class,"putTerm","(Ljava/lang/Object;Ljpl/fli/term_t;)V")) != NULL
01419
01420 && (lref=(*env)->FindClass(env,"jpl/fli/term_t")) != NULL
01421 && (termt_class=(*env)->NewGlobalRef(env,lref)) != NULL
01422 && ( (*env)->DeleteLocalRef(env,lref), TRUE)
01423
01424 ? 0
01425 : -7
01426 )
01427 ;
01428 }
01429
01430
01431
01432
01433
01434 static term_t
01435 jni_new_java_exception(
01436 atom_t tag,
01437 atom_t msg
01438 )
01439 {
01440 term_t e = PL_new_term_ref();
01441
01442 PL_unify_term(e,
01443 PL_FUNCTOR, JNI_functor_error_2,
01444 PL_FUNCTOR, JNI_functor_java_exception_1,
01445 PL_FUNCTOR, JNI_functor_at_1,
01446 PL_ATOM, tag,
01447 PL_ATOM, msg);
01448 return e;
01449 }
01450
01451
01452
01453 static term_t
01454 jni_new_jpl_error(
01455 atom_t tag,
01456 atom_t msg
01457 )
01458 {
01459 term_t e = PL_new_term_ref();
01460
01461 PL_unify_term(e,
01462 PL_FUNCTOR, JNI_functor_error_2,
01463 PL_FUNCTOR, JNI_functor_jpl_error_1,
01464 PL_FUNCTOR, JNI_functor_at_1,
01465 PL_ATOM, tag,
01466 PL_ATOM, msg);
01467 return e;
01468 }
01469
01470
01471
01472 static bool
01473 jni_check_exception(
01474 JNIEnv *env
01475 )
01476 {
01477 jobject ej;
01478 jobject c;
01479 jobject s;
01480 term_t ep;
01481 pointer i;
01482 atom_t tag;
01483 atom_t msg;
01484
01485 if ( (ej=(*env)->ExceptionOccurred(env)) == NULL )
01486 {
01487 return TRUE;
01488 }
01489 else
01490 {
01491 (*env)->ExceptionClear(env);
01492 if ( (c=(*env)->GetObjectClass(env,ej)) != NULL )
01493 {
01494 if ( (s=(*env)->CallObjectMethod(env,c,c_getName)) != NULL )
01495 {
01496 if ( jni_object_to_iref(env,ej,&i) )
01497 {
01498 if ( jni_iref_to_tag(i,&tag) )
01499 {
01500 if ( jni_String_to_atom(env,s,&msg) )
01501 {
01502 ep = jni_new_java_exception(tag,msg);
01503 }
01504 else
01505 {
01506 ep = jni_new_jpl_error(PL_new_atom("FailedToGetUTFCharsOfNameOfClassOfException"),tag);
01507 }
01508 }
01509 else
01510 {
01511 ep = jni_new_jpl_error(PL_new_atom("FailedToConvertExceptionIrefToTagatom"),JNI_atom_null);
01512 }
01513 }
01514 else
01515 {
01516 ep = jni_new_jpl_error(PL_new_atom("FailedToConvertExceptionObjectToIref"),JNI_atom_null);
01517 }
01518 (*env)->DeleteLocalRef(env,s);
01519 }
01520 else
01521 {
01522 ep = jni_new_jpl_error(PL_new_atom("FailedToGetNameOfClassOfException"),JNI_atom_null);
01523 }
01524 (*env)->DeleteLocalRef(env,c);
01525 }
01526 else
01527 {
01528 ep = jni_new_jpl_error(PL_new_atom("FailedToGetClassOfException"),JNI_atom_null);
01529 }
01530 return PL_raise_exception(ep);
01531 }
01532 }
01533
01534
01535
01536
01537 static foreign_t
01538 jni_byte_buf_length_to_codes_plc(
01539 term_t tbb,
01540 term_t tlen,
01541 term_t tcs
01542 )
01543 {
01544 functor_t fn;
01545 term_t a1;
01546 atom_t a;
01547 term_t a2;
01548 jbyte *bb;
01549 int len;
01550 int i;
01551 term_t tl = PL_copy_term_ref( tcs);
01552 term_t ta = PL_new_term_ref();
01553 void *ptr;
01554
01555 if ( !( PL_get_functor(tbb,&fn)
01556 && fn==JNI_functor_jbuf_2
01557 && ( a2=PL_new_term_ref(),
01558 PL_get_arg(2,tbb,a2)
01559 )
01560 && PL_get_atom(a2,&a)
01561 && a==JNI_atom_byte
01562 && ( a1=PL_new_term_ref(),
01563 PL_get_arg(1,tbb,a1)
01564 )
01565 && PL_get_pointer(a1,&ptr)
01566 )
01567 || !PL_get_integer(tlen,&len)
01568 )
01569 {
01570 return FALSE;
01571 }
01572 bb = ptr;
01573
01574 for ( i=0 ; i<len ; i++ )
01575 {
01576 if ( !PL_unify_list(tl,ta,tl)
01577 || !PL_unify_integer(ta,(int)(bb[i]))
01578 )
01579 {
01580 return FALSE;
01581 }
01582 }
01583 return PL_unify_nil( tl);
01584 }
01585
01586
01587 static foreign_t
01588 jni_param_put_plc(
01589 term_t tn,
01590 term_t txc,
01591 term_t tt,
01592 term_t tjvp
01593 )
01594 {
01595 int n;
01596 int xc;
01597 jvalue *jvp;
01598 functor_t fn;
01599 term_t a1;
01600 atom_t a;
01601 int i;
01602 int64_t i64;
01603 double d;
01604
01605 if ( !PL_get_integer(tn,&n) ||
01606 !PL_get_integer(txc,&xc) ||
01607 !PL_get_pointer(tjvp,(void*)&jvp) )
01608 {
01609 return FALSE;
01610 }
01611
01612 switch ( xc )
01613 {
01614 case JNI_XPUT_BOOLEAN:
01615 return JNI_term_to_jboolean(tt,jvp[n].z);
01616
01617 case JNI_XPUT_BYTE:
01618 return JNI_term_to_jbyte(tt,jvp[n].b);
01619
01620 case JNI_XPUT_CHAR:
01621 return JNI_term_to_jchar(tt,jvp[n].c);
01622
01623 case JNI_XPUT_SHORT:
01624 return JNI_term_to_jshort(tt,jvp[n].s);
01625
01626 case JNI_XPUT_INT:
01627 return JNI_term_to_jint(tt,jvp[n].i);
01628
01629 case JNI_XPUT_LONG:
01630 return JNI_term_to_jlong(tt,jvp[n].j);
01631
01632 case JNI_XPUT_FLOAT:
01633 return JNI_term_to_jfloat(tt,jvp[n].f);
01634
01635 case JNI_XPUT_DOUBLE:
01636 return JNI_term_to_jdouble(tt,jvp[n].d);
01637
01638 case JNI_XPUT_REF:
01639 { JNIEnv *env = jni_env();
01640
01641 return env == NULL ? FALSE : JNI_term_to_ref(tt,jvp[n].l);
01642 }
01643 default:
01644 return FALSE;
01645 }
01646 }
01647
01648
01649
01650 static foreign_t
01651 jni_alloc_buffer_plc(
01652 term_t txc,
01653 term_t tlen,
01654 term_t tbp
01655 )
01656 {
01657 int xc;
01658 int len;
01659 void *bp;
01660
01661 return PL_get_integer(txc,&xc)
01662 && ( ( xc>=JNI_XPUT_BOOLEAN && xc<=JNI_XPUT_DOUBLE ) || xc==JNI_XPUT_JVALUE )
01663 && PL_get_integer(tlen,&len)
01664 && len >= 0
01665 && (bp=malloc((len==0?1:len)*size[xc])) != NULL
01666 && ( PL_unify_pointer(tbp,(void*)bp)
01667 ? TRUE
01668 : ( free(bp), FALSE)
01669 )
01670 ;
01671 }
01672
01673
01674 static foreign_t
01675 jni_free_buffer_plc(
01676 term_t tbp
01677 )
01678 {
01679 void *bp;
01680
01681 return PL_get_pointer(tbp,&bp)
01682 && ( free(bp), TRUE);
01683 }
01684
01685
01686 static foreign_t
01687 jni_fetch_buffer_value_plc(
01688 term_t tbp,
01689 term_t ti,
01690 term_t tv,
01691 term_t txc
01692 )
01693 {
01694 void *bp;
01695 int i;
01696 int xc;
01697
01698 if ( !PL_get_pointer(tbp,&bp) || !PL_get_integer(ti,&i) || !PL_get_integer(txc,&xc) )
01699 {
01700 return FALSE;
01701 }
01702
01703 switch ( xc )
01704 {
01705 case JNI_XPUT_BOOLEAN:
01706 return JNI_jboolean_to_term(((jboolean*)bp)[i],tv);
01707
01708 case JNI_XPUT_CHAR:
01709 return PL_unify_integer(tv,((jchar*)bp)[i]);
01710
01711 case JNI_XPUT_BYTE:
01712 return PL_unify_integer(tv,((jbyte*)bp)[i]);
01713
01714 case JNI_XPUT_SHORT:
01715 return PL_unify_integer(tv,((jshort*)bp)[i]);
01716
01717 case JNI_XPUT_INT:
01718 return PL_unify_integer(tv,((jint*)bp)[i]);
01719
01720 case JNI_XPUT_LONG:
01721 return PL_unify_int64(tv,((jlong*)bp)[i]);
01722
01723 case JNI_XPUT_FLOAT:
01724 return PL_unify_float(tv,((jfloat*)bp)[i]);
01725
01726 case JNI_XPUT_DOUBLE:
01727 return PL_unify_float(tv,((jdouble*)bp)[i]);
01728
01729 default:
01730 return FALSE;
01731 }
01732 }
01733
01734
01735 static foreign_t
01736 jni_stash_buffer_value_plc(
01737 term_t tbp,
01738 term_t ti,
01739 term_t tv,
01740 term_t txc
01741 )
01742 {
01743 void *bp;
01744 int i;
01745 int idx;
01746 int64_t i64;
01747 int xc;
01748 double d;
01749 functor_t fn;
01750 term_t a1;
01751 atom_t a;
01752
01753 if ( !PL_get_pointer(tbp,&bp)
01754 || !PL_get_integer(ti,&idx)
01755 || !PL_get_integer(txc,&xc)
01756 )
01757 {
01758 return FALSE;
01759 }
01760
01761 switch ( xc )
01762 {
01763 case JNI_XPUT_BOOLEAN:
01764 return JNI_term_to_jboolean(tv,((jboolean*)bp)[idx]);
01765
01766 case JNI_XPUT_CHAR:
01767 return JNI_term_to_jchar(tv,((jchar*)bp)[idx]);
01768
01769 case JNI_XPUT_BYTE:
01770 return JNI_term_to_jbyte(tv,((jbyte*)bp)[idx]);
01771
01772 case JNI_XPUT_SHORT:
01773 return JNI_term_to_jshort(tv,((jshort*)bp)[idx]);
01774
01775 case JNI_XPUT_INT:
01776 return JNI_term_to_jint(tv,((jint*)bp)[idx]);
01777
01778 case JNI_XPUT_LONG:
01779 return JNI_term_to_jlong(tv,((jlong*)bp)[idx]);
01780
01781 case JNI_XPUT_FLOAT:
01782 return JNI_term_to_jfloat(tv,((jfloat*)bp)[idx]);
01783
01784 case JNI_XPUT_DOUBLE:
01785 return JNI_term_to_jdouble(tv,((jdouble*)bp)[idx]);
01786
01787 default:
01788 return FALSE;
01789 }
01790 }
01791
01792
01793
01794
01795 static int
01796 jni_get_created_jvm_count()
01797 {
01798 jint n;
01799
01800 return ( JNI_GetCreatedJavaVMs(NULL,0,&n) == 0
01801 ? n
01802 : -1
01803 )
01804 ;
01805 }
01806
01807
01808 #define MAX_JVM_OPTIONS 100
01809
01810 static int
01811 jni_create_jvm_c(
01812 char *classpath
01813 )
01814 {
01815 JavaVMInitArgs vm_args;
01816
01817 char *cpoptp;
01818 JavaVMOption opt[MAX_JVM_OPTIONS];
01819 int r;
01820 jint n;
01821 int optn = 0;
01822 JNIEnv *env;
01823
01824 DEBUG(1, Sdprintf( "[creating JVM with 'java.class.path=%s']\n", classpath));
01825 vm_args.version = JNI_VERSION_1_2;
01826 if ( classpath )
01827 {
01828 cpoptp = (char *)malloc(strlen(classpath)+20);
01829 strcpy( cpoptp, "-Djava.class.path=");
01830 strcat( cpoptp, classpath);
01831 vm_args.options = opt;
01832 opt[optn].optionString = cpoptp;
01833 optn++;
01834 }
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847 if ( jvm_dia != NULL )
01848 {
01849 int i;
01850
01851 for ( i=0 ; jvm_dia[i]!=NULL ; i++ )
01852 {
01853 opt[optn++].optionString = jvm_dia[i];
01854 }
01855 jvm_aia = jvm_dia;
01856 jvm_dia = NULL;
01857 }
01858
01859 vm_args.nOptions = optn;
01860
01861
01862 return
01863 ( JNI_GetCreatedJavaVMs(&jvm,1,&n) == 0
01864 && n == 1
01865
01866 && (env = jni_env()) != NULL
01867 ? 2
01868 : ( (r=JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args)) == 0
01869 ? 0
01870 : ( jvm=NULL, r)
01871 )
01872 );
01873 }
01874
01875
01876 static foreign_t
01877 jni_get_created_jvm_count_plc(
01878 term_t t1
01879 )
01880 {
01881
01882 return PL_unify_integer(t1,jni_get_created_jvm_count());
01883 }
01884
01885
01886 static int
01887 jni_create_jvm(
01888 char *cp
01889 )
01890 {
01891 int r1;
01892 int r2;
01893
01894 DEBUG(1, Sdprintf("[JPL: checking for Java VM...]\n"));
01895 return
01896 ( jvm != NULL
01897 ? 1
01898 : ( (r1=jni_create_jvm_c(cp)) < 0
01899 ? r1
01900 : ( (r2=jni_init()) < 0
01901 ? r2
01902 : ( r1 == 0
01903 ? ( DEBUG(0, Sdprintf("[JPL: Java VM created]\n")), r1)
01904 : ( DEBUG(0, Sdprintf("[JPL: Java VM found]\n")), r1)
01905 )
01906 )
01907 )
01908 );
01909 }
01910
01911
01912
01913
01914
01915
01916
01917
01918 int
01919 jni_create_default_jvm()
01920 {
01921 int r;
01922 #ifdef __WINDOWS__
01923 char *cp;
01924 DWORD len;
01925
01926 if ( (len=GetEnvironmentVariable("CLASSPATH", NULL, 0)) > 0 )
01927 { cp = malloc(len+1);
01928
01929 GetEnvironmentVariable("CLASSPATH", cp, len+1);
01930 } else
01931 cp = NULL;
01932 #else
01933 char *cp = getenv("CLASSPATH");
01934 #endif
01935
01936 DEBUG(0, Sdprintf("jni_create_default_jvm(): cp=%s\n", cp));
01937
01938 if ( (r=jni_create_jvm(cp)) < 0 )
01939 {
01940 Sdprintf("[JPL: failed to create Java VM (error %d)]\n", r);
01941 }
01942 return r >= 0;
01943 }
01944
01945
01946 static foreign_t
01947 jni_ensure_jvm_plc()
01948 {
01949 JNIEnv *env;
01950
01951 return jni_ensure_jvm();
01952 }
01953
01954
01955
01956
01957
01958 static foreign_t
01959 jni_void_0_plc(
01960 term_t tn
01961 )
01962 {
01963 int n;
01964 jboolean r;
01965 JNIEnv *env;
01966
01967 if ( !jni_ensure_jvm()
01968 || !PL_get_integer(tn,&n)
01969 )
01970 {
01971 return FALSE;
01972 }
01973
01974 switch ( n )
01975 {
01976 case 17:
01977 r = ( (*env)->ExceptionClear(env) , TRUE );
01978 break;
01979 default:
01980 return FALSE;
01981 break;
01982 }
01983
01984 return jni_check_exception(env) && r;
01985 }
01986
01987
01988 static foreign_t
01989 jni_void_1_plc(
01990 term_t tn,
01991 term_t ta1
01992 )
01993 {
01994 int n;
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006 char *c1;
02007
02008
02009
02010 jboolean r;
02011 JNIEnv *env;
02012
02013 if ( !jni_ensure_jvm()
02014 || !PL_get_integer(tn,&n)
02015 )
02016 {
02017 return FALSE;
02018 }
02019
02020 switch ( n )
02021 {
02022 case 18:
02023 r = JNI_term_to_charP(ta1,c1)
02024 && ( (*env)->FatalError(env,(char*)c1) , TRUE );
02025 break;
02026 default:
02027 return FALSE;
02028 break;
02029 }
02030
02031 return jni_check_exception(env) && r;
02032 }
02033
02034
02035 static foreign_t
02036 jni_void_2_plc(
02037 term_t tn,
02038 term_t ta1,
02039 term_t ta2
02040 )
02041 {
02042 int n;
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063 jboolean r;
02064 JNIEnv *env;
02065
02066 if ( !jni_ensure_jvm()
02067 || !PL_get_integer(tn,&n)
02068 )
02069 {
02070 return FALSE;
02071 }
02072
02073 switch ( n )
02074 {
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085 default:
02086 return FALSE;
02087 break;
02088 }
02089
02090 return jni_check_exception(env) && r;
02091 }
02092
02093
02094 static foreign_t
02095 jni_void_3_plc(
02096 term_t tn,
02097 term_t ta1,
02098 term_t ta2,
02099 term_t ta3
02100 )
02101 {
02102 int n;
02103 functor_t fn;
02104 term_t a1;
02105
02106 atom_t a;
02107
02108 int i;
02109 int64_t i64;
02110 double d;
02111
02112
02113
02114
02115 void *p1;
02116 void *p2;
02117 void *p3;
02118
02119
02120
02121
02122 int i2;
02123 int i3;
02124
02125
02126 jlong l3;
02127
02128
02129 float f3;
02130
02131
02132 double d3;
02133 jvalue *jvp = NULL;
02134 jboolean r;
02135 JNIEnv *env;
02136
02137 if ( !jni_ensure_jvm()
02138 || !PL_get_integer(tn,&n)
02139 )
02140 {
02141 return FALSE;
02142 }
02143
02144 switch ( n )
02145 {
02146 case 63:
02147 r = JNI_term_to_jobject(ta1,p1)
02148 && JNI_term_to_jmethodID(ta2,p2)
02149 && JNI_term_to_pointer(ta3,jvp)
02150 && ( (*env)->CallVoidMethodA(env,(jobject)p1,(jmethodID)p2,jvp) , TRUE );
02151 break;
02152 case 104:
02153 r = JNI_term_to_jobject(ta1,p1)
02154 && JNI_term_to_jfieldID(ta2,p2)
02155 && JNI_term_to_ref(ta3,p3)
02156 && ( (*env)->SetObjectField(env,(jobject)p1,(jfieldID)p2,(jobject)p3) , TRUE );
02157 break;
02158 case 105:
02159 r = JNI_term_to_jobject(ta1,p1)
02160 && JNI_term_to_jfieldID(ta2,p2)
02161 && JNI_term_to_jboolean(ta3,i3)
02162 && ( (*env)->SetBooleanField(env,(jobject)p1,(jfieldID)p2,(jboolean)i3) , TRUE );
02163 break;
02164 case 106:
02165 r = JNI_term_to_jobject(ta1,p1)
02166 && JNI_term_to_jfieldID(ta2,p2)
02167 && JNI_term_to_jbyte(ta3,i3)
02168 && ( (*env)->SetByteField(env,(jobject)p1,(jfieldID)p2,(jbyte)i3) , TRUE );
02169 break;
02170 case 107:
02171 r = JNI_term_to_jobject(ta1,p1)
02172 && JNI_term_to_jfieldID(ta2,p2)
02173 && JNI_term_to_jchar(ta3,i3)
02174 && ( (*env)->SetCharField(env,(jobject)p1,(jfieldID)p2,(jchar)i3) , TRUE );
02175 break;
02176 case 108:
02177 r = JNI_term_to_jobject(ta1,p1)
02178 && JNI_term_to_jfieldID(ta2,p2)
02179 && JNI_term_to_jshort(ta3,i3)
02180 && ( (*env)->SetShortField(env,(jobject)p1,(jfieldID)p2,(jshort)i3) , TRUE );
02181 break;
02182 case 109:
02183 r = JNI_term_to_jobject(ta1,p1)
02184 && JNI_term_to_jfieldID(ta2,p2)
02185 && JNI_term_to_jint(ta3,i3)
02186 && ( (*env)->SetIntField(env,(jobject)p1,(jfieldID)p2,(jint)i3) , TRUE );
02187 break;
02188 case 110:
02189 r = JNI_term_to_jobject(ta1,p1)
02190 && JNI_term_to_jfieldID(ta2,p2)
02191 && JNI_term_to_jlong(ta3,l3)
02192 && ( (*env)->SetLongField(env,(jobject)p1,(jfieldID)p2,(jlong)l3) , TRUE );
02193 break;
02194 case 111:
02195 r = JNI_term_to_jobject(ta1,p1)
02196 && JNI_term_to_jfieldID(ta2,p2)
02197 && JNI_term_to_jfloat(ta3,f3)
02198 && ( (*env)->SetFloatField(env,(jobject)p1,(jfieldID)p2,(jfloat)f3) , TRUE );
02199 break;
02200 case 112:
02201 r = JNI_term_to_jobject(ta1,p1)
02202 && JNI_term_to_jfieldID(ta2,p2)
02203 && JNI_term_to_jdouble(ta3,d3)
02204 && ( (*env)->SetDoubleField(env,(jobject)p1,(jfieldID)p2,(jdouble)d3) , TRUE );
02205 break;
02206 case 143:
02207 r = JNI_term_to_jclass(ta1,p1)
02208 && JNI_term_to_jmethodID(ta2,p2)
02209 && JNI_term_to_pointer(ta3,jvp)
02210 && ( (*env)->CallStaticVoidMethodA(env,(jclass)p1,(jmethodID)p2,jvp) , TRUE );
02211 break;
02212 case 154:
02213 r = JNI_term_to_jclass(ta1,p1)
02214 && JNI_term_to_jfieldID(ta2,p2)
02215 && JNI_term_to_ref(ta3,p3)
02216 && ( (*env)->SetStaticObjectField(env,(jclass)p1,(jfieldID)p2,(jobject)p3) , TRUE );
02217 break;
02218 case 155:
02219 r = JNI_term_to_jclass(ta1,p1)
02220 && JNI_term_to_jfieldID(ta2,p2)
02221 && JNI_term_to_jboolean(ta3,i3)
02222 && ( (*env)->SetStaticBooleanField(env,(jclass)p1,(jfieldID)p2,(jboolean)i3) , TRUE );
02223 break;
02224 case 156:
02225 r = JNI_term_to_jclass(ta1,p1)
02226 && JNI_term_to_jfieldID(ta2,p2)
02227 && JNI_term_to_jbyte(ta3,i3)
02228 && ( (*env)->SetStaticByteField(env,(jclass)p1,(jfieldID)p2,(jbyte)i3) , TRUE );
02229 break;
02230 case 157:
02231 r = JNI_term_to_jclass(ta1,p1)
02232 && JNI_term_to_jfieldID(ta2,p2)
02233 && JNI_term_to_jchar(ta3,i3)
02234 && ( (*env)->SetStaticCharField(env,(jclass)p1,(jfieldID)p2,(jchar)i3) , TRUE );
02235 break;
02236 case 158:
02237 r = JNI_term_to_jclass(ta1,p1)
02238 && JNI_term_to_jfieldID(ta2,p2)
02239 && JNI_term_to_jshort(ta3,i3)
02240 && ( (*env)->SetStaticShortField(env,(jclass)p1,(jfieldID)p2,(jshort)i3) , TRUE );
02241 break;
02242 case 159:
02243 r = JNI_term_to_jclass(ta1,p1)
02244 && JNI_term_to_jfieldID(ta2,p2)
02245 && JNI_term_to_jint(ta3,i3)
02246 && ( (*env)->SetStaticIntField(env,(jclass)p1,(jfieldID)p2,(jint)i3) , TRUE );
02247 break;
02248 case 160:
02249 r = JNI_term_to_jclass(ta1,p1)
02250 && JNI_term_to_jfieldID(ta2,p2)
02251 && JNI_term_to_jlong(ta3,l3)
02252 && ( (*env)->SetStaticLongField(env,(jclass)p1,(jfieldID)p2,(jlong)l3) , TRUE );
02253 break;
02254 case 161:
02255 r = JNI_term_to_jclass(ta1,p1)
02256 && JNI_term_to_jfieldID(ta2,p2)
02257 && JNI_term_to_jfloat(ta3,f3)
02258 && ( (*env)->SetStaticFloatField(env,(jclass)p1,(jfieldID)p2,(jfloat)f3) , TRUE );
02259 break;
02260 case 162:
02261 r = JNI_term_to_jclass(ta1,p1)
02262 && JNI_term_to_jfieldID(ta2,p2)
02263 && JNI_term_to_jdouble(ta3,d3)
02264 && ( (*env)->SetStaticDoubleField(env,(jclass)p1,(jfieldID)p2,(jdouble)d3) , TRUE );
02265 break;
02266 case 174:
02267 r = JNI_term_to_object_jarray(ta1,p1)
02268 && JNI_term_to_jint(ta2,i2)
02269 && JNI_term_to_ref(ta3,p3)
02270 && ( (*env)->SetObjectArrayElement(env,(jobjectArray)p1,(jsize)i2,(jobject)p3) , TRUE );
02271 break;
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320 default:
02321 return FALSE;
02322 break;
02323 }
02324
02325 if ( jvp != NULL )
02326 {
02327 free( jvp);
02328 }
02329
02330 return jni_check_exception(env) && r;
02331 }
02332
02333
02334 static foreign_t
02335 jni_void_4_plc(
02336 term_t tn,
02337 term_t ta1,
02338 term_t ta2,
02339 term_t ta3,
02340 term_t ta4
02341 )
02342 {
02343 int n;
02344 functor_t fn;
02345 term_t a1;
02346 term_t a2;
02347 atom_t a;
02348
02349 int i;
02350
02351
02352
02353
02354 void *p1;
02355
02356
02357 void *p4;
02358
02359
02360
02361
02362
02363 int i2;
02364 int i3;
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374 jvalue *jvp = NULL;
02375 jboolean r;
02376 JNIEnv *env;
02377
02378 if ( !jni_ensure_jvm()
02379 || !PL_get_integer(tn,&n)
02380 )
02381 {
02382 return FALSE;
02383 }
02384
02385 switch ( n )
02386 {
02387
02388
02389
02390
02391
02392
02393
02394 case 199:
02395 r = JNI_term_to_boolean_jarray(ta1,p1)
02396 && JNI_term_to_jint(ta2,i2)
02397 && JNI_term_to_jint(ta3,i3)
02398 && JNI_term_to_jbuf(ta4,p4,JNI_atom_boolean)
02399 && ( (*env)->GetBooleanArrayRegion(env,(jbooleanArray)p1,(jsize)i2,(jsize)i3,(jboolean*)p4) , TRUE );
02400 break;
02401 case 200:
02402 r = JNI_term_to_byte_jarray(ta1,p1)
02403 && JNI_term_to_jint(ta2,i2)
02404 && JNI_term_to_jint(ta3,i3)
02405 && JNI_term_to_jbuf(ta4,p4,JNI_atom_byte)
02406 && ( (*env)->GetByteArrayRegion(env,(jbyteArray)p1,(jsize)i2,(jsize)i3,(jbyte*)p4) , TRUE );
02407 break;
02408 case 201:
02409 r = JNI_term_to_char_jarray(ta1,p1)
02410 && JNI_term_to_jint(ta2,i2)
02411 && JNI_term_to_jint(ta3,i3)
02412 && JNI_term_to_jbuf(ta4,p4,JNI_atom_char)
02413 && ( (*env)->GetCharArrayRegion(env,(jcharArray)p1,(jsize)i2,(jsize)i3,(jchar*)p4) , TRUE );
02414 break;
02415 case 202:
02416 r = JNI_term_to_short_jarray(ta1,p1)
02417 && JNI_term_to_jint(ta2,i2)
02418 && JNI_term_to_jint(ta3,i3)
02419 && JNI_term_to_jbuf(ta4,p4,JNI_atom_short)
02420 && ( (*env)->GetShortArrayRegion(env,(jshortArray)p1,(jsize)i2,(jsize)i3,(jshort*)p4) , TRUE );
02421 break;
02422 case 203:
02423 r = JNI_term_to_int_jarray(ta1,p1)
02424 && JNI_term_to_jint(ta2,i2)
02425 && JNI_term_to_jint(ta3,i3)
02426 && JNI_term_to_jbuf(ta4,p4,JNI_atom_int)
02427 && ( (*env)->GetIntArrayRegion(env,(jintArray)p1,(jsize)i2,(jsize)i3,(jint*)p4) , TRUE );
02428 break;
02429 case 204:
02430 r = JNI_term_to_long_jarray(ta1,p1)
02431 && JNI_term_to_jint(ta2,i2)
02432 && JNI_term_to_jint(ta3,i3)
02433 && JNI_term_to_jbuf(ta4,p4,JNI_atom_long)
02434 && ( (*env)->GetLongArrayRegion(env,(jlongArray)p1,(jsize)i2,(jsize)i3,(jlong*)p4) , TRUE );
02435 break;
02436 case 205:
02437 r = JNI_term_to_float_jarray(ta1,p1)
02438 && JNI_term_to_jint(ta2,i2)
02439 && JNI_term_to_jint(ta3,i3)
02440 && JNI_term_to_jbuf(ta4,p4,JNI_atom_float)
02441 && ( (*env)->GetFloatArrayRegion(env,(jfloatArray)p1,(jsize)i2,(jsize)i3,(jfloat*)p4) , TRUE );
02442 break;
02443 case 206:
02444 r = JNI_term_to_double_jarray(ta1,p1)
02445 && JNI_term_to_jint(ta2,i2)
02446 && JNI_term_to_jint(ta3,i3)
02447 && JNI_term_to_jbuf(ta4,p4,JNI_atom_double)
02448 && ( (*env)->GetDoubleArrayRegion(env,(jdoubleArray)p1,(jsize)i2,(jsize)i3,(jdouble*)p4) , TRUE );
02449 break;
02450 case 207:
02451 r = JNI_term_to_boolean_jarray(ta1,p1)
02452 && JNI_term_to_jint(ta2,i2)
02453 && JNI_term_to_jint(ta3,i3)
02454 && JNI_term_to_jbuf(ta4,p4,JNI_atom_boolean)
02455 && ( (*env)->SetBooleanArrayRegion(env,(jbooleanArray)p1,(jsize)i2,(jsize)i3,(jboolean*)p4) , TRUE );
02456 break;
02457 case 208:
02458 r = JNI_term_to_byte_jarray(ta1,p1)
02459 && JNI_term_to_jint(ta2,i2)
02460 && JNI_term_to_jint(ta3,i3)
02461 && JNI_term_to_jbuf(ta4,p4,JNI_atom_byte)
02462 && ( (*env)->SetByteArrayRegion(env,(jbyteArray)p1,(jsize)i2,(jsize)i3,(jbyte*)p4) , TRUE );
02463 break;
02464 case 209:
02465 r = JNI_term_to_char_jarray(ta1,p1)
02466 && JNI_term_to_jint(ta2,i2)
02467 && JNI_term_to_jint(ta3,i3)
02468 && JNI_term_to_jbuf(ta4,p4,JNI_atom_char)
02469 && ( (*env)->SetCharArrayRegion(env,(jcharArray)p1,(jsize)i2,(jsize)i3,(jchar*)p4) , TRUE );
02470 break;
02471 case 210:
02472 r = JNI_term_to_short_jarray(ta1,p1)
02473 && JNI_term_to_jint(ta2,i2)
02474 && JNI_term_to_jint(ta3,i3)
02475 && JNI_term_to_jbuf(ta4,p4,JNI_atom_short)
02476 && ( (*env)->SetShortArrayRegion(env,(jshortArray)p1,(jsize)i2,(jsize)i3,(jshort*)p4) , TRUE );
02477 break;
02478 case 211:
02479 r = JNI_term_to_int_jarray(ta1,p1)
02480 && JNI_term_to_jint(ta2,i2)
02481 && JNI_term_to_jint(ta3,i3)
02482 && JNI_term_to_jbuf(ta4,p4,JNI_atom_int)
02483 && ( (*env)->SetIntArrayRegion(env,(jintArray)p1,(jsize)i2,(jsize)i3,(jint*)p4) , TRUE );
02484 break;
02485 case 212:
02486 r = JNI_term_to_long_jarray(ta1,p1)
02487 && JNI_term_to_jint(ta2,i2)
02488 && JNI_term_to_jint(ta3,i3)
02489 && JNI_term_to_jbuf(ta4,p4,JNI_atom_long)
02490 && ( (*env)->SetLongArrayRegion(env,(jlongArray)p1,(jsize)i2,(jsize)i3,(jlong*)p4) , TRUE );
02491 break;
02492 case 213:
02493 r = JNI_term_to_float_jarray(ta1,p1)
02494 && JNI_term_to_jint(ta2,i2)
02495 && JNI_term_to_jint(ta3,i3)
02496 && JNI_term_to_jbuf(ta4,p4,JNI_atom_float)
02497 && ( (*env)->SetFloatArrayRegion(env,(jfloatArray)p1,(jsize)i2,(jsize)i3,(jfloat*)p4) , TRUE );
02498 break;
02499 case 214:
02500 r = JNI_term_to_double_jarray(ta1,p1)
02501 && JNI_term_to_jint(ta2,i2)
02502 && JNI_term_to_jint(ta3,i3)
02503 && JNI_term_to_jbuf(ta4,p4,JNI_atom_double)
02504 && ( (*env)->SetDoubleArrayRegion(env,(jdoubleArray)p1,(jsize)i2,(jsize)i3,(jdouble*)p4) , TRUE );
02505 break;
02506 default:
02507 return FALSE;
02508 break;
02509 }
02510
02511 if ( jvp != NULL )
02512 {
02513 free( jvp);
02514 }
02515
02516 return jni_check_exception(env) && r;
02517 }
02518
02519
02520 static foreign_t
02521 jni_func_0_plc(
02522 term_t tn,
02523 term_t tr
02524 )
02525 {
02526 int n;
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537 jboolean r;
02538 JNIEnv *env;
02539
02540 if ( !jni_ensure_jvm()
02541 || !PL_get_integer(tn,&n)
02542 )
02543 {
02544 return FALSE;
02545 }
02546
02547 switch ( n )
02548 {
02549
02550
02551
02552
02553
02554
02555 default:
02556 return FALSE;
02557 break;
02558 }
02559
02560 return jni_check_exception(env) && r;
02561 }
02562
02563
02564 static foreign_t
02565 jni_func_1_plc(
02566 term_t tn,
02567 term_t ta1,
02568 term_t tr
02569 )
02570 {
02571 int n;
02572 functor_t fn;
02573 term_t a1;
02574
02575 atom_t a;
02576
02577 pointer i;
02578
02579
02580 jobject j;
02581
02582 void *p1;
02583 char *c1;
02584 int i1;
02585
02586
02587 jboolean r;
02588 JNIEnv *env;
02589
02590 if ( !jni_ensure_jvm()
02591 || !PL_get_integer(tn,&n)
02592 )
02593 {
02594 return FALSE;
02595 }
02596
02597 switch ( n )
02598 {
02599 case 6:
02600 r = JNI_term_to_charP(ta1,c1)
02601 && JNI_jobject_to_term((*env)->FindClass(env,(char*)c1),tr);
02602 break;
02603 case 10:
02604 r = JNI_term_to_jclass(ta1,p1)
02605 && JNI_jobject_to_term((*env)->GetSuperclass(env,(jclass)p1),tr);
02606 break;
02607
02608
02609
02610
02611
02612
02613
02614
02615 case 31:
02616 r = JNI_term_to_jobject(ta1,p1)
02617 && JNI_jobject_to_term((*env)->GetObjectClass(env,(jobject)p1),tr);
02618 break;
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631 case 171:
02632 r = JNI_term_to_jarray(ta1,p1)
02633 && JNI_jint_to_term((*env)->GetArrayLength(env,(jarray)p1),tr);
02634 break;
02635 case 175:
02636 r = JNI_term_to_non_neg_jint(ta1,i1)
02637 && JNI_jobject_to_term((*env)->NewBooleanArray(env,(jsize)i1),tr);
02638 break;
02639 case 176:
02640 r = JNI_term_to_non_neg_jint(ta1,i1)
02641 && JNI_jobject_to_term((*env)->NewByteArray(env,(jsize)i1),tr);
02642 break;
02643 case 177:
02644 r = JNI_term_to_non_neg_jint(ta1,i1)
02645 && JNI_jobject_to_term((*env)->NewCharArray(env,(jsize)i1),tr);
02646 break;
02647 case 178:
02648 r = JNI_term_to_non_neg_jint(ta1,i1)
02649 && JNI_jobject_to_term((*env)->NewShortArray(env,(jsize)i1),tr);
02650 break;
02651 case 179:
02652 r = JNI_term_to_non_neg_jint(ta1,i1)
02653 && JNI_jobject_to_term((*env)->NewIntArray(env,(jsize)i1),tr);
02654 break;
02655 case 180:
02656 r = JNI_term_to_non_neg_jint(ta1,i1)
02657 && JNI_jobject_to_term((*env)->NewLongArray(env,(jsize)i1),tr);
02658 break;
02659 case 181:
02660 r = JNI_term_to_non_neg_jint(ta1,i1)
02661 && JNI_jobject_to_term((*env)->NewFloatArray(env,(jsize)i1),tr);
02662 break;
02663 case 182:
02664 r = JNI_term_to_non_neg_jint(ta1,i1)
02665 && JNI_jobject_to_term((*env)->NewDoubleArray(env,(jsize)i1),tr);
02666 break;
02667
02668
02669
02670
02671
02672
02673
02674
02675 default:
02676 return FALSE;
02677 break;
02678 }
02679
02680 return jni_check_exception(env) && r;
02681 }
02682
02683
02684 static foreign_t
02685 jni_func_2_plc(
02686 term_t tn,
02687 term_t ta1,
02688 term_t ta2,
02689 term_t tr
02690 )
02691 {
02692 int n;
02693 functor_t fn;
02694 term_t a1;
02695
02696 atom_t a;
02697
02698 pointer i;
02699
02700
02701 jobject j;
02702
02703 void *p1;
02704 void *p2;
02705
02706
02707
02708 int i2;
02709
02710
02711
02712
02713 jboolean r;
02714 JNIEnv *env;
02715
02716 if ( !jni_ensure_jvm()
02717 || !PL_get_integer(tn,&n)
02718 )
02719 {
02720 return FALSE;
02721 }
02722
02723 switch ( n )
02724 {
02725 case 11:
02726 r = JNI_term_to_jclass(ta1,p1)
02727 && JNI_term_to_jclass(ta2,p2)
02728 && JNI_jboolean_to_term((*env)->IsAssignableFrom(env,(jclass)p1,(jclass)p2),tr);
02729 break;
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745 case 95:
02746 r = JNI_term_to_jobject(ta1,p1)
02747 && JNI_term_to_jfieldID(ta2,p2)
02748 && JNI_jobject_to_term((*env)->GetObjectField(env,(jobject)p1,(jfieldID)p2),tr);
02749 break;
02750 case 96:
02751 r = JNI_term_to_jobject(ta1,p1)
02752 && JNI_term_to_jfieldID(ta2,p2)
02753 && JNI_jboolean_to_term((*env)->GetBooleanField(env,(jobject)p1,(jfieldID)p2),tr);
02754 break;
02755 case 97:
02756 r = JNI_term_to_jobject(ta1,p1)
02757 && JNI_term_to_jfieldID(ta2,p2)
02758 && JNI_jbyte_to_term((*env)->GetByteField(env,(jobject)p1,(jfieldID)p2),tr);
02759 break;
02760 case 98:
02761 r = JNI_term_to_jobject(ta1,p1)
02762 && JNI_term_to_jfieldID(ta2,p2)
02763 && JNI_jchar_to_term((*env)->GetCharField(env,(jobject)p1,(jfieldID)p2),tr);
02764 break;
02765 case 99:
02766 r = JNI_term_to_jobject(ta1,p1)
02767 && JNI_term_to_jfieldID(ta2,p2)
02768 && JNI_jshort_to_term((*env)->GetShortField(env,(jobject)p1,(jfieldID)p2),tr);
02769 break;
02770 case 100:
02771 r = JNI_term_to_jobject(ta1,p1)
02772 && JNI_term_to_jfieldID(ta2,p2)
02773 && JNI_jint_to_term((*env)->GetIntField(env,(jobject)p1,(jfieldID)p2),tr);
02774 break;
02775 case 101:
02776 r = JNI_term_to_jobject(ta1,p1)
02777 && JNI_term_to_jfieldID(ta2,p2)
02778 && JNI_jlong_to_term((*env)->GetLongField(env,(jobject)p1,(jfieldID)p2),tr);
02779 break;
02780 case 102:
02781 r = JNI_term_to_jobject(ta1,p1)
02782 && JNI_term_to_jfieldID(ta2,p2)
02783 && JNI_jfloat_to_term((*env)->GetFloatField(env,(jobject)p1,(jfieldID)p2),tr);
02784 break;
02785 case 103:
02786 r = JNI_term_to_jobject(ta1,p1)
02787 && JNI_term_to_jfieldID(ta2,p2)
02788 && JNI_jdouble_to_term((*env)->GetDoubleField(env,(jobject)p1,(jfieldID)p2),tr);
02789 break;
02790 case 145:
02791 r = JNI_term_to_jclass(ta1,p1)
02792 && JNI_term_to_jfieldID(ta2,p2)
02793 && JNI_jobject_to_term((*env)->GetStaticObjectField(env,(jclass)p1,(jfieldID)p2),tr);
02794 break;
02795 case 146:
02796 r = JNI_term_to_jclass(ta1,p1)
02797 && JNI_term_to_jfieldID(ta2,p2)
02798 && JNI_jboolean_to_term((*env)->GetStaticBooleanField(env,(jclass)p1,(jfieldID)p2),tr);
02799 break;
02800 case 147:
02801 r = JNI_term_to_jclass(ta1,p1)
02802 && JNI_term_to_jfieldID(ta2,p2)
02803 && JNI_jbyte_to_term((*env)->GetStaticByteField(env,(jclass)p1,(jfieldID)p2),tr);
02804 break;
02805 case 148:
02806 r = JNI_term_to_jclass(ta1,p1)
02807 && JNI_term_to_jfieldID(ta2,p2)
02808 && JNI_jchar_to_term((*env)->GetStaticCharField(env,(jclass)p1,(jfieldID)p2),tr);
02809 break;
02810 case 149:
02811 r = JNI_term_to_jclass(ta1,p1)
02812 && JNI_term_to_jfieldID(ta2,p2)
02813 && JNI_jshort_to_term((*env)->GetStaticShortField(env,(jclass)p1,(jfieldID)p2),tr);
02814 break;
02815 case 150:
02816 r = JNI_term_to_jclass(ta1,p1)
02817 && JNI_term_to_jfieldID(ta2,p2)
02818 && JNI_jint_to_term((*env)->GetStaticIntField(env,(jclass)p1,(jfieldID)p2),tr);
02819 break;
02820 case 151:
02821 r = JNI_term_to_jclass(ta1,p1)
02822 && JNI_term_to_jfieldID(ta2,p2)
02823 && JNI_jlong_to_term((*env)->GetStaticLongField(env,(jclass)p1,(jfieldID)p2),tr);
02824 break;
02825 case 152:
02826 r = JNI_term_to_jclass(ta1,p1)
02827 && JNI_term_to_jfieldID(ta2,p2)
02828 && JNI_jfloat_to_term((*env)->GetStaticFloatField(env,(jclass)p1,(jfieldID)p2),tr);
02829 break;
02830 case 153:
02831 r = JNI_term_to_jclass(ta1,p1)
02832 && JNI_term_to_jfieldID(ta2,p2)
02833 && JNI_jdouble_to_term((*env)->GetStaticDoubleField(env,(jclass)p1,(jfieldID)p2),tr);
02834 break;
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850 case 173:
02851 { int i;
02852
02853 i2 = 0;
02854 r = JNI_term_to_object_jarray(ta1,p1)
02855 && JNI_term_to_jint(ta2,i2);
02856 }
02857 if ( r )
02858 r = JNI_jobject_to_term((*env)->GetObjectArrayElement(env,(jobjectArray)p1,(jsize)i2),tr);
02859 break;
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900 default:
02901 return FALSE;
02902 break;
02903 }
02904
02905 return jni_check_exception(env) && r;
02906 }
02907
02908
02909 static foreign_t
02910 jni_func_3_plc(
02911 term_t tn,
02912 term_t ta1,
02913 term_t ta2,
02914 term_t ta3,
02915 term_t tr
02916 )
02917 {
02918 int n;
02919 functor_t fn;
02920 term_t a1;
02921
02922 atom_t a;
02923
02924 pointer i;
02925
02926
02927 jobject j;
02928
02929 void *p1;
02930 void *p2;
02931 void *p3;
02932
02933 char *c2;
02934 char *c3;
02935 int i1;
02936
02937
02938
02939
02940
02941
02942
02943
02944 jvalue *jvp = NULL;
02945 jboolean r;
02946 JNIEnv *env;
02947
02948 if ( !jni_ensure_jvm()
02949 || !PL_get_integer(tn,&n)
02950 )
02951 {
02952 return FALSE;
02953 }
02954
02955 switch ( n )
02956 {
02957 case 30:
02958 r = JNI_term_to_non_array_jclass(ta1,p1)
02959 && JNI_term_to_jmethodID(ta2,p2)
02960 && JNI_term_to_pointer(ta3,jvp)
02961 && JNI_jobject_to_term((*env)->NewObjectA(env,(jclass)p1,(jmethodID)p2,jvp),tr);
02962 break;
02963 case 33:
02964 r = JNI_term_to_jclass(ta1,p1)
02965 && JNI_term_to_charP(ta2,c2)
02966 && JNI_term_to_charP(ta3,c3)
02967 && JNI_jmethodID_to_term((*env)->GetMethodID(env,(jclass)p1,(char*)c2,(char*)c3),tr);
02968 break;
02969 case 36:
02970 r = JNI_term_to_jobject(ta1,p1)
02971 && JNI_term_to_jmethodID(ta2,p2)
02972 && JNI_term_to_pointer(ta3,jvp)
02973 && JNI_jobject_to_term((*env)->CallObjectMethodA(env,(jobject)p1,(jmethodID)p2,jvp),tr);
02974 break;
02975 case 39:
02976 r = JNI_term_to_jobject(ta1,p1)
02977 && JNI_term_to_jmethodID(ta2,p2)
02978 && JNI_term_to_pointer(ta3,jvp)
02979 && JNI_jboolean_to_term((*env)->CallBooleanMethodA(env,(jobject)p1,(jmethodID)p2,jvp),tr);
02980 break;
02981 case 42:
02982 r = JNI_term_to_jobject(ta1,p1)
02983 && JNI_term_to_jmethodID(ta2,p2)
02984 && JNI_term_to_pointer(ta3,jvp)
02985 && JNI_jbyte_to_term((*env)->CallByteMethodA(env,(jobject)p1,(jmethodID)p2,jvp),tr);
02986 break;
02987 case 45:
02988 r = JNI_term_to_jobject(ta1,p1)
02989 && JNI_term_to_jmethodID(ta2,p2)
02990 && JNI_term_to_pointer(ta3,jvp)
02991 && JNI_jchar_to_term((*env)->CallCharMethodA(env,(jobject)p1,(jmethodID)p2,jvp),tr);
02992 break;
02993 case 48:
02994 r = JNI_term_to_jobject(ta1,p1)
02995 && JNI_term_to_jmethodID(ta2,p2)
02996 && JNI_term_to_pointer(ta3,jvp)
02997 && JNI_jshort_to_term((*env)->CallShortMethodA(env,(jobject)p1,(jmethodID)p2,jvp),tr);
02998 break;
02999 case 51:
03000 r = JNI_term_to_jobject(ta1,p1)
03001 && JNI_term_to_jmethodID(ta2,p2)
03002 && JNI_term_to_pointer(ta3,jvp)
03003 && JNI_jint_to_term((*env)->CallIntMethodA(env,(jobject)p1,(jmethodID)p2,jvp),tr);
03004 break;
03005 case 54:
03006 r = JNI_term_to_jobject(ta1,p1)
03007 && JNI_term_to_jmethodID(ta2,p2)
03008 && JNI_term_to_pointer(ta3,jvp)
03009 && JNI_jlong_to_term((*env)->CallLongMethodA(env,(jobject)p1,(jmethodID)p2,jvp),tr);
03010 break;
03011 case 57:
03012 r = JNI_term_to_jobject(ta1,p1)
03013 && JNI_term_to_jmethodID(ta2,p2)
03014 && JNI_term_to_pointer(ta3,jvp)
03015 && JNI_jfloat_to_term((*env)->CallFloatMethodA(env,(jobject)p1,(jmethodID)p2,jvp),tr);
03016 break;
03017 case 60:
03018 r = JNI_term_to_jobject(ta1,p1)
03019 && JNI_term_to_jmethodID(ta2,p2)
03020 && JNI_term_to_pointer(ta3,jvp)
03021 && JNI_jdouble_to_term((*env)->CallDoubleMethodA(env,(jobject)p1,(jmethodID)p2,jvp),tr);
03022 break;
03023 case 94:
03024 r = JNI_term_to_jclass(ta1,p1)
03025 && JNI_term_to_charP(ta2,c2)
03026 && JNI_term_to_charP(ta3,c3)
03027 && JNI_jfieldID_to_term((*env)->GetFieldID(env,(jclass)p1,(char*)c2,(char*)c3),tr);
03028 break;
03029 case 113:
03030 r = JNI_term_to_jclass(ta1,p1)
03031 && JNI_term_to_charP(ta2,c2)
03032 && JNI_term_to_charP(ta3,c3)
03033 && JNI_jmethodID_to_term((*env)->GetStaticMethodID(env,(jclass)p1,(char*)c2,(char*)c3),tr);
03034 break;
03035 case 116:
03036 r = JNI_term_to_jclass(ta1,p1)
03037 && JNI_term_to_jmethodID(ta2,p2)
03038 && JNI_term_to_pointer(ta3,jvp)
03039 && JNI_jobject_to_term((*env)->CallStaticObjectMethodA(env,(jclass)p1,(jmethodID)p2,jvp),tr);
03040 break;
03041 case 119:
03042 r = JNI_term_to_jclass(ta1,p1)
03043 && JNI_term_to_jmethodID(ta2,p2)
03044 && JNI_term_to_pointer(ta3,jvp)
03045 && JNI_jboolean_to_term((*env)->CallStaticBooleanMethodA(env,(jclass)p1,(jmethodID)p2,jvp),tr);
03046 break;
03047 case 122:
03048 r = JNI_term_to_jclass(ta1,p1)
03049 && JNI_term_to_jmethodID(ta2,p2)
03050 && JNI_term_to_pointer(ta3,jvp)
03051 && JNI_jbyte_to_term((*env)->CallStaticByteMethodA(env,(jclass)p1,(jmethodID)p2,jvp),tr);
03052 break;
03053 case 125:
03054 r = JNI_term_to_jclass(ta1,p1)
03055 && JNI_term_to_jmethodID(ta2,p2)
03056 && JNI_term_to_pointer(ta3,jvp)
03057 && JNI_jchar_to_term((*env)->CallStaticCharMethodA(env,(jclass)p1,(jmethodID)p2,jvp),tr);
03058 break;
03059 case 128:
03060 r = JNI_term_to_jclass(ta1,p1)
03061 && JNI_term_to_jmethodID(ta2,p2)
03062 && JNI_term_to_pointer(ta3,jvp)
03063 && JNI_jshort_to_term((*env)->CallStaticShortMethodA(env,(jclass)p1,(jmethodID)p2,jvp),tr);
03064 break;
03065 case 131:
03066 r = JNI_term_to_jclass(ta1,p1)
03067 && JNI_term_to_jmethodID(ta2,p2)
03068 && JNI_term_to_pointer(ta3,jvp)
03069 && JNI_jint_to_term((*env)->CallStaticIntMethodA(env,(jclass)p1,(jmethodID)p2,jvp),tr);
03070 break;
03071 case 134:
03072 r = JNI_term_to_jclass(ta1,p1)
03073 && JNI_term_to_jmethodID(ta2,p2)
03074 && JNI_term_to_pointer(ta3,jvp)
03075 && JNI_jlong_to_term((*env)->CallStaticLongMethodA(env,(jclass)p1,(jmethodID)p2,jvp),tr);
03076 break;
03077 case 137:
03078 r = JNI_term_to_jclass(ta1,p1)
03079 && JNI_term_to_jmethodID(ta2,p2)
03080 && JNI_term_to_pointer(ta3,jvp)
03081 && JNI_jfloat_to_term((*env)->CallStaticFloatMethodA(env,(jclass)p1,(jmethodID)p2,jvp),tr);
03082 break;
03083 case 140:
03084 r = JNI_term_to_jclass(ta1,p1)
03085 && JNI_term_to_jmethodID(ta2,p2)
03086 && JNI_term_to_pointer(ta3,jvp)
03087 && JNI_jdouble_to_term((*env)->CallStaticDoubleMethodA(env,(jclass)p1,(jmethodID)p2,jvp),tr);
03088 break;
03089 case 144:
03090 r = JNI_term_to_jclass(ta1,p1)
03091 && JNI_term_to_charP(ta2,c2)
03092 && JNI_term_to_charP(ta3,c3)
03093 && JNI_jfieldID_to_term((*env)->GetStaticFieldID(env,(jclass)p1,(char*)c2,(char*)c3),tr);
03094 break;
03095 case 172:
03096 r = JNI_term_to_non_neg_jint(ta1,i1)
03097 && JNI_term_to_jclass(ta2,p2)
03098 && JNI_term_to_ref(ta3,p3)
03099 && JNI_jobject_to_term((*env)->NewObjectArray(env,(jsize)i1,(jclass)p2,(jobject)p3),tr);
03100 break;
03101 default:
03102 return FALSE;
03103 break;
03104 }
03105
03106 if ( jvp != NULL )
03107 {
03108 free( jvp);
03109 }
03110
03111 return jni_check_exception(env) && r;
03112 }
03113
03114
03115 static foreign_t
03116 jni_func_4_plc(
03117 term_t tn,
03118 term_t ta1,
03119 term_t ta2,
03120 term_t ta3,
03121 term_t ta4,
03122 term_t tr
03123 )
03124 {
03125 int n;
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156 jvalue *jvp = NULL;
03157 jboolean r;
03158 JNIEnv *env;
03159
03160 if ( !jni_ensure_jvm()
03161 || !PL_get_integer(tn,&n)
03162 )
03163 {
03164 return FALSE;
03165 }
03166
03167 switch ( n )
03168 {
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239 default:
03240 return FALSE;
03241 break;
03242 }
03243
03244 if ( jvp != NULL )
03245 {
03246 free( jvp);
03247 }
03248
03249 return jni_check_exception(env) && r;
03250 }
03251
03252
03253
03254
03255 static int
03256 create_pool_engines();
03257
03258 static int
03259 jpl_num_initial_default_args()
03260 {
03261 int i;
03262
03263 for ( i=0 ; default_args[i]!=NULL ; i++ )
03264 {
03265 }
03266 return i;
03267 }
03268
03269
03270
03271
03272
03273 static bool
03274 jpl_do_jpl_init(
03275 JNIEnv *env
03276 )
03277 {
03278 jclass tc;
03279 jobject ta;
03280 char *msg;
03281 int i;
03282 jobject to;
03283
03284 if ( jpl_status != JPL_INIT_RAW )
03285 {
03286 DEBUG(1, Sdprintf( "[JPL: jpl_do_jpl_init() called AGAIN (skipping...)]\n"));
03287 return TRUE;
03288 }
03289
03290
03291 if ( (tc=(*env)->FindClass(env,"java/lang/String")) == NULL
03292 || (jString_c=(*env)->NewGlobalRef(env,tc)) == NULL
03293 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03294
03295 || (ta=(*env)->NewObjectArray(env,jpl_num_initial_default_args(),jString_c,NULL)) == NULL
03296 || (pvm_dia=(*env)->NewGlobalRef(env,ta)) == NULL
03297 || ( (*env)->DeleteLocalRef(env,ta), FALSE)
03298 )
03299 {
03300 msg = "jpl_do_jpl_init(): failed to find java.lang.String or create String[] pvm_dia";
03301 goto err;
03302 }
03303
03304
03305 for ( i=0 ; default_args[i]!=NULL ; i++ )
03306 {
03307 if ( (to=(*env)->NewStringUTF(env,default_args[i])) == NULL )
03308 {
03309 msg = "jpl_do_jpl_init(): failed to convert an initial default arg to a String";
03310 goto err;
03311 }
03312 (*env)->SetObjectArrayElement(env,pvm_dia,i,to);
03313 }
03314
03315 if ( (tc=(*env)->FindClass(env,"jpl/JPLException")) == NULL
03316 || (jJPLException_c=(*env)->NewGlobalRef(env,tc)) == NULL
03317 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03318
03319 || (tc=(*env)->FindClass(env,"jpl/fli/term_t")) == NULL
03320 || (jTermT_c=(*env)->NewGlobalRef(env,tc)) == NULL
03321 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03322
03323 || (tc=(*env)->FindClass(env,"jpl/fli/atom_t")) == NULL
03324 || (jAtomT_c=(*env)->NewGlobalRef(env,tc)) == NULL
03325 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03326
03327 || (tc=(*env)->FindClass(env,"jpl/fli/functor_t")) == NULL
03328 || (jFunctorT_c=(*env)->NewGlobalRef(env,tc)) == NULL
03329 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03330
03331 || (tc=(*env)->FindClass(env,"jpl/fli/fid_t")) == NULL
03332 || (jFidT_c=(*env)->NewGlobalRef(env,tc)) == NULL
03333 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03334
03335 || (tc=(*env)->FindClass(env,"jpl/fli/predicate_t")) == NULL
03336 || (jPredicateT_c=(*env)->NewGlobalRef(env,tc)) == NULL
03337 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03338
03339 || (tc=(*env)->FindClass(env,"jpl/fli/qid_t")) == NULL
03340 || (jQidT_c=(*env)->NewGlobalRef(env,tc)) == NULL
03341 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03342
03343 || (tc=(*env)->FindClass(env,"jpl/fli/module_t")) == NULL
03344 || (jModuleT_c=(*env)->NewGlobalRef(env,tc)) == NULL
03345 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03346
03347 || (tc=(*env)->FindClass(env,"jpl/fli/engine_t")) == NULL
03348 || (jEngineT_c=(*env)->NewGlobalRef(env,tc)) == NULL
03349 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03350
03351 || (tc=(*env)->FindClass(env,"jpl/fli/LongHolder")) == NULL
03352 || (jLongHolder_c=(*env)->NewGlobalRef(env,tc)) == NULL
03353 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03354
03355 || (tc=(*env)->FindClass(env,"jpl/fli/PointerHolder")) == NULL
03356 || (jPointerHolder_c=(*env)->NewGlobalRef(env,tc)) == NULL
03357 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03358
03359 || (tc=(*env)->FindClass(env,"jpl/fli/IntHolder")) == NULL
03360 || (jIntHolder_c=(*env)->NewGlobalRef(env,tc)) == NULL
03361 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03362
03363 || (tc=(*env)->FindClass(env,"jpl/fli/Int64Holder")) == NULL
03364 || (jInt64Holder_c=(*env)->NewGlobalRef(env,tc)) == NULL
03365 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03366
03367 || (tc=(*env)->FindClass(env,"jpl/fli/DoubleHolder")) == NULL
03368 || (jDoubleHolder_c=(*env)->NewGlobalRef(env,tc)) == NULL
03369 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03370
03371 || (tc=(*env)->FindClass(env,"jpl/fli/StringHolder")) == NULL
03372 || (jStringHolder_c=(*env)->NewGlobalRef(env,tc)) == NULL
03373 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03374
03375 || (tc=(*env)->FindClass(env,"jpl/fli/ObjectHolder")) == NULL
03376 || (jObjectHolder_c=(*env)->NewGlobalRef(env,tc)) == NULL
03377 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03378
03379 || (tc=(*env)->FindClass(env,"jpl/fli/BooleanHolder")) == NULL
03380 || (jBooleanHolder_c=(*env)->NewGlobalRef(env,tc)) == NULL
03381 || ( (*env)->DeleteLocalRef(env,tc), FALSE)
03382
03383 || (jLongHolderValue_f=(*env)->GetFieldID(env,jLongHolder_c,"value","J")) == NULL
03384
03385 || (jPointerHolderValue_f=(*env)->GetFieldID(env,jPointerHolder_c,"value","J")) == NULL
03386
03387 || (jIntHolderValue_f=(*env)->GetFieldID(env,jIntHolder_c,"value","I")) == NULL
03388
03389 || (jInt64HolderValue_f=(*env)->GetFieldID(env,jInt64Holder_c,"value","J")) == NULL
03390
03391 || (jDoubleHolderValue_f=(*env)->GetFieldID(env,jDoubleHolder_c,"value","D")) == NULL
03392
03393 || (jStringHolderValue_f=(*env)->GetFieldID(env,jStringHolder_c,"value","Ljava/lang/String;")) == NULL
03394
03395 || (jObjectHolderValue_f=(*env)->GetFieldID(env,jObjectHolder_c,"value","Ljava/lang/Object;")) == NULL
03396
03397 || (jBooleanHolderValue_f=(*env)->GetFieldID(env,jBooleanHolder_c,"value","Z")) == NULL
03398 )
03399 {
03400 msg = "jpl_do_jpl_init(): failed to find jpl.* or jpl.fli.* classes";
03401 goto err;
03402 }
03403
03404 DEBUG(1, Sdprintf( "[jpl_do_jpl_init() sets jpl_status = JPL_INIT_PVM_MAYBE, returns TRUE]\n"));
03405 jpl_status = JPL_INIT_PVM_MAYBE;
03406 return TRUE;
03407
03408 err:
03409 jpl_status = JPL_INIT_JPL_FAILED;
03410 (*env)->ThrowNew(env,jJPLException_c,msg);
03411 return FALSE;
03412 }
03413
03414
03415
03416
03417
03418
03419
03420 static bool
03421 jpl_post_pvm_init(
03422 JNIEnv *env,
03423 int argc,
03424 char **argv
03425 )
03426 {
03427 char *msg;
03428 jobject ta;
03429 int i;
03430
03431
03432
03433 pvm_dia = NULL;
03434 if ( (ta=(*env)->NewObjectArray(env,argc,jString_c,NULL)) == NULL
03435 || (pvm_aia=(*env)->NewGlobalRef(env,ta)) == NULL
03436 || ( (*env)->DeleteLocalRef(env,ta), FALSE)
03437 )
03438 {
03439 msg = "jpl_post_pvm_init(): failed to copy actual init args";
03440 goto err;
03441 }
03442 for ( i=0 ; i<argc ; i++ )
03443 {
03444 jobject to;
03445
03446 to = (*env)->NewStringUTF(env,argv[i]);
03447 if ( to == NULL )
03448 {
03449 msg = "jpl_post_pvm_init(): failed to convert actual PL init arg to String";
03450 goto err;
03451 }
03452 (*env)->SetObjectArrayElement(env,pvm_aia,i,to);
03453 }
03454
03455 if ( create_pool_engines() != 0 )
03456 {
03457 msg = "jpl_post_pvm_init(): failed to create Prolog engine pool";
03458 goto err;
03459 }
03460
03461 jpl_status = JPL_INIT_OK;
03462 return TRUE;
03463
03464 err:
03465 (*env)->ThrowNew( env, jJPLException_c, msg);
03466 jpl_status = JPL_INIT_PVM_FAILED;
03467 return FALSE;
03468 }
03469
03470
03471
03472
03473
03474
03475
03476 static bool
03477 jpl_test_pvm_init(
03478 JNIEnv *env
03479 )
03480 {
03481 char *msg;
03482 int argc;
03483 char **argv;
03484
03485
03486
03487 if ( jpl_status == JPL_INIT_RAW )
03488 {
03489 msg = "jpl_test_pvm_init(): called while jpl_status == JPL_INIT_RAW";
03490 goto err;
03491 }
03492
03493 if ( jpl_status==JPL_INIT_JPL_FAILED || jpl_status==JPL_INIT_PVM_FAILED )
03494 {
03495 msg = "jpl_test_pvm_init(): initialisation has already failed";
03496 goto err;
03497 }
03498
03499 if ( jpl_status == JPL_INIT_OK )
03500 {
03501 return TRUE;
03502 }
03503
03504 if ( jpl_status == JPL_INIT_PVM_MAYBE )
03505 {
03506
03507 if ( !PL_is_initialised(&argc,&argv) )
03508 {
03509
03510 DEBUG(1, Sdprintf( "[pl_test_pvm_init(): PL is not yet initialised: returning FALSE]\n"));
03511 return FALSE;
03512 }
03513 else
03514 {
03515 DEBUG(1, Sdprintf( "[pl_test_pvm_init(): PL is already initialised: proceeding to jpl_post_pvm_init()]\n"));
03516 return jpl_post_pvm_init(env,argc,argv);
03517 }
03518 }
03519
03520 msg = "jpl_test_pvm_init(): unknown jpl_status value";
03521 goto err;
03522
03523 err:
03524 (*env)->ThrowNew( env, jJPLException_c, msg);
03525 jpl_status = JPL_INIT_PVM_FAILED;
03526 return FALSE;
03527 }
03528
03529
03530
03531
03532
03533
03534
03535 static bool
03536 jpl_do_pvm_init(
03537 JNIEnv *env
03538 )
03539 {
03540 char *msg;
03541 int argc;
03542 char **argv;
03543 int i;
03544 jstring arg;
03545 char *cp;
03546
03547
03548 if ( jpl_status != JPL_INIT_PVM_MAYBE )
03549 {
03550 msg = "jpl_do_pvm_init(): called while jpl_status != JPL_INIT_PVM_MAYBE";
03551 goto err;
03552 }
03553
03554
03555 if ( pvm_dia == NULL )
03556 {
03557 msg = "jpl_do_pvm_init(): pvm_dia == NULL";
03558 goto err;
03559 }
03560 argc = (*env)->GetArrayLength(env,pvm_dia);
03561 if ( argc <= 0 )
03562 {
03563 msg = "jpl_do_pvm_init(): there are fewer than 1 default init args";
03564 goto err;
03565 }
03566 if ( (argv=(char**)malloc((argc+1)*sizeof(char*))) == NULL )
03567 {
03568 msg = "jpl_do_pvm_init(): malloc() failed for argv";
03569 goto err;
03570 }
03571 for ( i=0 ; i<argc ; i++ )
03572 {
03573 arg = (jstring)(*env)->GetObjectArrayElement(env,pvm_dia,i);
03574 cp = (char*)(*env)->GetStringUTFChars(env,arg,0);
03575 argv[i] = (char*)malloc(strlen(cp)+1);
03576 strcpy( argv[i], cp);
03577 DEBUG(1, Sdprintf( " argv[%d] = %s\n", i, argv[i]));
03578 (*env)->ReleaseStringUTFChars( env, arg, cp);
03579 }
03580 DEBUG(1, Sdprintf( " argv[%d] = NULL\n", argc));
03581 argv[argc] = NULL;
03582 if ( !PL_initialise(argc,(char**)argv) )
03583 {
03584 msg = "jpl_do_pvm_init(): PL_initialise() failed";
03585 goto err;
03586 }
03587
03588
03589 return jpl_post_pvm_init(env,argc,argv);
03590
03591 err:
03592 jpl_status = JPL_INIT_PVM_FAILED;
03593 (*env)->ThrowNew( env, jJPLException_c, msg);
03594 return FALSE;
03595 }
03596
03597
03598 static bool
03599 jpl_ensure_jpl_init_1(
03600 JNIEnv *env
03601 )
03602 {
03603 bool r;
03604
03605 pthread_mutex_lock( &jvm_init_mutex);
03606 r = jpl_do_jpl_init(env);
03607 pthread_mutex_unlock( &jvm_init_mutex);
03608 return r;
03609 }
03610
03611
03612 static bool
03613 jpl_ensure_pvm_init_1(
03614 JNIEnv *env
03615 )
03616 {
03617 bool r;
03618
03619 pthread_mutex_lock( &pvm_init_mutex);
03620 if ( !jpl_ensure_jpl_init(env) )
03621 return FALSE;
03622 r = jpl_test_pvm_init(env) || jpl_do_pvm_init(env);
03623 pthread_mutex_unlock( &pvm_init_mutex);
03624 return r;
03625 }
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636
03637
03638 JNIEXPORT jobject JNICALL
03639 Java_jpl_fli_Prolog_get_1default_1init_1args(
03640 JNIEnv *env,
03641 jclass jProlog
03642 )
03643 {
03644 char *msg;
03645
03646 if ( !jpl_ensure_jpl_init(env) )
03647 return FALSE;
03648
03649 if ( jpl_status==JPL_INIT_JPL_FAILED || jpl_status==JPL_INIT_PVM_FAILED )
03650 {
03651 msg = "jpl.fli.Prolog.set_default_init_args(): initialisation has already failed";
03652 goto err;
03653 }
03654
03655 return ( jpl_test_pvm_init(env)
03656 ? NULL
03657 : pvm_dia
03658 )
03659 ;
03660 err:
03661 (*env)->ThrowNew( env, jJPLException_c, msg);
03662 return FALSE;
03663 }
03664
03665
03666
03667
03668
03669
03670
03671
03672
03673
03674
03675 JNIEXPORT jboolean JNICALL
03676 Java_jpl_fli_Prolog_set_1default_1init_1args(
03677 JNIEnv *env,
03678 jclass jProlog,
03679 jobject jargs
03680 )
03681 {
03682 char *msg;
03683
03684 if ( !jpl_ensure_jpl_init(env) )
03685 return FALSE;
03686
03687 if ( jargs == NULL )
03688 {
03689 msg = "jpl.fli.Prolog.set_default_init_args() called with NULL arg";
03690 goto err;
03691 }
03692
03693 if ( jpl_status==JPL_INIT_JPL_FAILED || jpl_status==JPL_INIT_PVM_FAILED )
03694 {
03695 msg = "jpl.fli.Prolog.set_default_init_args(): initialisation has already failed";
03696 goto err;
03697 }
03698
03699 if ( jpl_test_pvm_init(env) )
03700 {
03701 return FALSE;
03702 }
03703 else
03704 {
03705 pvm_dia = NULL;
03706 pvm_dia = (*env)->NewGlobalRef(env,jargs);
03707 return TRUE;
03708 }
03709
03710 err:
03711 (*env)->ThrowNew( env, jJPLException_c, msg);
03712 return FALSE;
03713 }
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724 JNIEXPORT jobject JNICALL
03725 Java_jpl_fli_Prolog_get_1actual_1init_1args(
03726 JNIEnv *env,
03727 jclass jProlog
03728 )
03729 {
03730 char *msg;
03731
03732 if ( !jpl_ensure_jpl_init( env) )
03733 return NULL;
03734
03735 if ( jpl_status==JPL_INIT_JPL_FAILED || jpl_status==JPL_INIT_PVM_FAILED )
03736 {
03737 msg = "jpl.fli.Prolog.get_actual_init_args(): initialisation has already failed";
03738 goto err;
03739 }
03740
03741 return ( jpl_test_pvm_init(env)
03742 ? pvm_aia
03743 : NULL
03744 );
03745
03746 err:
03747 (*env)->ThrowNew( env, jJPLException_c, msg);
03748 return NULL;
03749 }
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760 JNIEXPORT jboolean JNICALL
03761 Java_jpl_fli_Prolog_initialise(
03762 JNIEnv *env,
03763 jclass jProlog
03764 )
03765 {
03766 char *msg;
03767
03768 if ( !jpl_ensure_jpl_init( env) )
03769 return FALSE;
03770
03771 if ( jpl_status==JPL_INIT_JPL_FAILED || jpl_status==JPL_INIT_PVM_FAILED )
03772 {
03773 msg = "jpl.fli.Prolog.initialise(): initialisation has already failed";
03774 goto err;
03775 }
03776
03777 if ( jpl_test_pvm_init(env) )
03778 {
03779 return FALSE;
03780 }
03781 else
03782 {
03783 jpl_do_pvm_init( env);
03784 return jpl_test_pvm_init(env);
03785 }
03786
03787 err:
03788 (*env)->ThrowNew( env, jJPLException_c, msg);
03789 return FALSE;
03790 }
03791
03792
03793
03794
03795
03796
03797
03798 JNIEXPORT void JNICALL
03799 Java_jpl_fli_Prolog_halt(
03800 JNIEnv *env,
03801 jclass jProlog,
03802 jint jstatus
03803 )
03804 {
03805
03806 (void)jpl_ensure_pvm_init(env);
03807 PL_halt( (int)jstatus);
03808 }
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823 static bool
03824 getLongValue(
03825 JNIEnv *env,
03826 jobject jlong_holder,
03827 long *lv
03828 )
03829 {
03830
03831 if ( jlong_holder == NULL )
03832 {
03833 *lv = 0L;
03834 return FALSE;
03835 }
03836 else
03837 {
03838 *lv = (long)(*env)->GetLongField(env,jlong_holder,jLongHolderValue_f);
03839 return TRUE;
03840 }
03841 }
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852
03853
03854 static bool
03855 getPointerValue(
03856 JNIEnv *env,
03857 jobject jpointer_holder,
03858 pointer *pv
03859 )
03860 {
03861
03862 if ( jpointer_holder == NULL )
03863 {
03864 *pv = (pointer)NULL;
03865 return FALSE;
03866 }
03867 else
03868 {
03869 *pv = (pointer)(*env)->GetLongField(env,jpointer_holder,jPointerHolderValue_f);
03870 return TRUE;
03871 }
03872 }
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885 static bool
03886 setPointerValue(
03887 JNIEnv *env,
03888 jobject jpointer_holder,
03889 pointer pv
03890 )
03891 {
03892
03893 return jpointer_holder != NULL
03894 && ( (*env)->SetLongField(env,jpointer_holder,jPointerHolderValue_f,(long)pv),
03895 TRUE
03896 )
03897 ;
03898 }
03899
03900
03901
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911 static bool
03912 setIntValue(
03913 JNIEnv *env,
03914 jobject jint_holder,
03915 jint iv
03916 )
03917 {
03918
03919 return jint_holder != NULL
03920 && ( (*env)->SetIntField(env,jint_holder,jIntHolderValue_f,iv),
03921 TRUE
03922 )
03923 ;
03924 }
03925
03926
03927 #if 0
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938 static bool
03939 setInt64Value(
03940 JNIEnv *env,
03941 jobject jint64_holder,
03942 int64_t i64v
03943 )
03944 {
03945
03946 return jint64_holder != NULL
03947 && ( (*env)->SetLongField(env,jint64_holder,jInt64HolderValue_f,i64v),
03948 TRUE
03949 )
03950 ;
03951 }
03952 #endif
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965 static bool
03966 setLongValue(
03967 JNIEnv *env,
03968 jobject jlong_holder,
03969 jlong lv
03970 )
03971 {
03972
03973 return jlong_holder != NULL
03974 && ( (*env)->SetLongField(env,jlong_holder,jLongHolderValue_f,lv),
03975 TRUE
03976 )
03977 ;
03978 }
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990
03991 static bool
03992 setDoubleValue(
03993 JNIEnv *env,
03994 jobject jdouble_holder,
03995 jdouble dv
03996 )
03997 {
03998
03999 return jdouble_holder != NULL
04000 && ( (*env)->SetDoubleField(env,jdouble_holder,jDoubleHolderValue_f,dv),
04001 TRUE
04002 )
04003 ;
04004 }
04005
04006
04007
04008
04009
04010
04011
04012
04013
04014
04015
04016
04017 static bool
04018 setStringValue(
04019 JNIEnv *env,
04020 jobject jstring_holder,
04021 jstring sv
04022 )
04023 {
04024
04025 return jstring_holder != NULL
04026 && ( (*env)->SetObjectField(env,jstring_holder,jStringHolderValue_f,sv),
04027 TRUE
04028 )
04029 ;
04030 }
04031
04032
04033 #if 0
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044 static bool
04045 setObjectValue(
04046 JNIEnv *env,
04047 jobject jobject_holder,
04048 jobject ref
04049 )
04050 {
04051
04052 return jobject_holder != NULL
04053 && ( (*env)->SetObjectField(env,jobject_holder,jObjectHolderValue_f,ref),
04054 TRUE
04055 )
04056 ;
04057 }
04058
04059
04060
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070 static bool
04071 setBooleanValue(
04072 JNIEnv *env,
04073 jobject jboolean_holder,
04074 jboolean jb
04075 )
04076 {
04077
04078 return jboolean_holder != NULL
04079 && ( (*env)->SetBooleanField(env,jboolean_holder,jBooleanHolderValue_f,jb),
04080 TRUE
04081 )
04082 ;
04083 }
04084
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097 static bool
04098 updateAtomValue(
04099 JNIEnv *env,
04100 jobject jatom_holder,
04101 atom_t atom2
04102 )
04103 {
04104 atom_t atom1;
04105
04106 if ( jatom_holder == NULL )
04107 {
04108 return FALSE;
04109 }
04110 else
04111 {
04112 atom1 = (atom_t)(*env)->GetLongField(env,jatom_holder,jLongHolderValue_f);
04113 if ( atom1 != 0L )
04114 {
04115 PL_unregister_atom( atom1);
04116 }
04117 (*env)->SetLongField(env,jatom_holder,jLongHolderValue_f,(long)atom2);
04118 if ( atom2 != 0L )
04119 {
04120 PL_register_atom( atom2);
04121 }
04122 return TRUE;
04123 }
04124 }
04125 #endif
04126
04127
04128
04129 static int current_pool_engine_handle(PL_engine_t *e);
04130 static int current_pool_engine();
04131
04132
04133
04134
04135
04136
04137
04138 JNIEXPORT int JNICALL
04139 Java_jpl_fli_Prolog_action_1abort(
04140 JNIEnv *env,
04141 jclass jProlog
04142 )
04143 {
04144
04145 if ( jpl_ensure_pvm_init(env) )
04146 {
04147 return PL_action(PL_ACTION_ABORT);
04148 }
04149 else
04150 {
04151 return -2;
04152 }
04153 }
04154
04155
04156
04157
04158
04159
04160
04161 JNIEXPORT jstring JNICALL
04162 Java_jpl_fli_Prolog_atom_1chars(
04163 JNIEnv *env,
04164 jclass jProlog,
04165 jobject jatom
04166 )
04167 {
04168 atom_t atom;
04169 jstring lref;
04170
04171 return ( jpl_ensure_pvm_init(env)
04172 && getLongValue(env,jatom,(long*)&atom)
04173 && jni_atom_to_String(env,atom,&lref)
04174 ? lref
04175 : NULL
04176 )
04177 ;
04178 }
04179
04180
04181
04182
04183
04184
04185
04186 JNIEXPORT int JNICALL
04187 Java_jpl_fli_Prolog_attach_1engine(
04188 JNIEnv *env,
04189 jclass jProlog,
04190 jobject jengine
04191 )
04192 {
04193 PL_engine_t engine;
04194 int rc;
04195
04196 if ( !jpl_ensure_pvm_init(env) )
04197 {
04198 return -2;
04199 }
04200
04201 rc = current_pool_engine_handle(&engine);
04202 DEBUG(0, Sdprintf( "attach_engine(): current_engine=%p, thread_self=%d, pool_id=%d\n", engine, PL_thread_self(), rc));
04203
04204 if ( !getPointerValue(env,jengine,(pointer*)&engine) )
04205 {
04206 return -3;
04207 }
04208
04209 DEBUG(0, Sdprintf( "attach_engine(): new_engine=%p\n", engine));
04210
04211 if ( (rc=PL_set_engine(engine,NULL)) == PL_ENGINE_SET )
04212 {
04213 return 0;
04214 }
04215 else
04216 {
04217 return -1;
04218 }
04219
04220 }
04221
04222
04223
04224
04225
04226
04227
04228 JNIEXPORT void JNICALL
04229 Java_jpl_fli_Prolog_close_1query(
04230 JNIEnv *env,
04231 jclass jProlog,
04232 jobject jqid
04233 )
04234 {
04235 qid_t qid;
04236
04237 DEBUG(1, Sdprintf( ">close_query(env=%lu,jProlog=%lu,jquid=%u)...\n", (long)env, (long)jProlog, (long)jqid));
04238 if ( jpl_ensure_pvm_init(env)
04239 && getLongValue(env,jqid,(long*)&qid)
04240 )
04241 {
04242 PL_close_query( qid);
04243 DEBUG(1, Sdprintf( " ok: PL_close_query(%lu)\n", (long)qid));
04244 }
04245 }
04246
04247
04248
04249
04250
04251
04252
04253 JNIEXPORT jint JNICALL
04254 Java_jpl_fli_Prolog_compare(
04255 JNIEnv *env,
04256 jclass jProlog,
04257 jobject jterm1,
04258 jobject jterm2
04259 )
04260 {
04261 term_t term1;
04262 term_t term2;
04263
04264 DEBUG(1, Sdprintf( ">compare(term1=%lu,term2=%lu)\n", (long)jterm1, (long)jterm2));
04265 if ( jpl_ensure_pvm_init(env)
04266 && getLongValue(env,jterm1,(long*)&term1)
04267 && getLongValue(env,jterm2,(long*)&term2)
04268 )
04269 {
04270 DEBUG(1, Sdprintf( "> PL_compare( %u, %u)", term1, term2));
04271 return PL_compare(term1,term2);
04272 }
04273 else
04274 {
04275 return -2;
04276 }
04277 }
04278
04279
04280
04281
04282
04283
04284
04285 JNIEXPORT void JNICALL
04286 Java_jpl_fli_Prolog_cons_1functor_1v(
04287 JNIEnv *env,
04288 jclass jProlog,
04289 jobject jterm,
04290 jobject jfunctor,
04291 jobject jterm0
04292 )
04293 {
04294 term_t term;
04295 functor_t functor;
04296 term_t term0;
04297
04298 if ( jpl_ensure_pvm_init(env)
04299 && getLongValue(env,jterm,(long*)&term)
04300 && getLongValue(env,jfunctor,(long*)&functor)
04301 && getLongValue(env,jterm0,(long*)&term0)
04302 )
04303 {
04304 PL_cons_functor_v( term, functor, term0);
04305 }
04306 }
04307
04308
04309
04310
04311
04312
04313
04314 JNIEXPORT jobject JNICALL
04315 Java_jpl_fli_Prolog_copy_1term_1ref(
04316 JNIEnv *env,
04317 jclass jProlog,
04318 jobject jfrom
04319 )
04320 {
04321 jobject rval;
04322 term_t term;
04323 term_t term2;
04324
04325 return ( jpl_ensure_pvm_init(env)
04326
04327 && getLongValue(env,jfrom,(long*)&term)
04328 && (rval=(*env)->AllocObject(env,jTermT_c)) != NULL
04329 && ( (term2=PL_copy_term_ref(term)) , TRUE )
04330 && setLongValue(env,rval,(long)term2)
04331 ? rval
04332 : NULL
04333 )
04334 ;
04335 }
04336
04337
04338
04339
04340
04341
04342
04343 JNIEXPORT jobject JNICALL
04344 Java_jpl_fli_Prolog_current_1engine(
04345 JNIEnv *env,
04346 jclass jProlog
04347 )
04348 {
04349 PL_engine_t engine;
04350 jobject rval;
04351
04352 return ( jpl_ensure_pvm_init(env)
04353 && PL_thread_self() != -1
04354 && ( current_pool_engine_handle(&engine) , TRUE )
04355 && (rval=(*env)->AllocObject(env,jEngineT_c)) != NULL
04356 && setPointerValue(env,rval,(pointer)engine)
04357 ? rval
04358 : NULL
04359 )
04360 ;
04361 }
04362
04363
04364
04365
04366
04367
04368
04369 JNIEXPORT jboolean JNICALL
04370 Java_jpl_fli_Prolog_current_1engine_1is_1pool(
04371 JNIEnv *env,
04372 jclass jProlog
04373 )
04374 {
04375
04376 if ( jpl_ensure_pvm_init(env) )
04377 {
04378 return current_pool_engine() >= 0;
04379 }
04380 else
04381 {
04382 return FALSE;
04383 }
04384 }
04385
04386
04387
04388
04389
04390
04391
04392 JNIEXPORT jobject JNICALL
04393 Java_jpl_fli_Prolog_exception(
04394 JNIEnv *env,
04395 jclass jProlog,
04396 jobject jqid
04397 )
04398 {
04399 qid_t qid;
04400 term_t term;
04401 jobject term_t;
04402
04403 DEBUG(1, Sdprintf( ">exception(jqid=%lu)\n", (long)jqid));
04404 return ( jpl_ensure_pvm_init(env)
04405 && ( DEBUG(1, Sdprintf( " ok: jpl_ensure_pvm_init(env)\n")), TRUE )
04406
04407 && ( DEBUG(1, Sdprintf( " ok: jqid != NULL\n")), TRUE )
04408 && getLongValue(env,jqid,(long*)&qid)
04409 && ( DEBUG(1, Sdprintf( " ok: getLongValue(env,jqid,(long*)&qid)\n")), TRUE )
04410 && ( (term=PL_exception(qid)) , TRUE )
04411 && ( DEBUG(1, Sdprintf(" ok: ( (term=PL_exception(qid)), TRUE)\n")), TRUE )
04412 && (term_t=(*env)->AllocObject(env,jTermT_c)) != NULL
04413 && ( DEBUG(1, Sdprintf( " ok: (term_t=(*env)->AllocObject(env,jTermT_c)) != NULL\n")), TRUE )
04414 && setLongValue(env,term_t,(long)term)
04415 && ( DEBUG(1, Sdprintf( " ok: setLongValue(env,term_t,(long)term)\n")), TRUE )
04416 ? (
04417 DEBUG(1, Sdprintf(" =%lu\n",(long)term_t)),
04418 term_t
04419 )
04420 : NULL
04421 )
04422 ;
04423 }
04424
04425
04426
04427
04428
04429
04430
04431 JNIEXPORT jboolean JNICALL
04432 Java_jpl_fli_Prolog_get_1arg(
04433 JNIEnv *env,
04434 jclass jProlog,
04435 jint jindex,
04436 jobject jterm,
04437 jobject jarg
04438 )
04439 {
04440 term_t term;
04441 term_t arg;
04442
04443 return jpl_ensure_pvm_init(env)
04444 && jarg != NULL
04445 && getLongValue(env,jterm,(long*)&term)
04446 && ( arg=PL_new_term_ref() , TRUE )
04447 && PL_get_arg(jindex,term,arg)
04448 && setLongValue(env,jarg,(long)arg)
04449 ;
04450 }
04451
04452
04453
04454
04455
04456
04457
04458 JNIEXPORT jboolean JNICALL
04459 Java_jpl_fli_Prolog_get_1atom_1chars(
04460 JNIEnv *env,
04461 jclass jProlog,
04462 jobject jterm,
04463 jobject jstring_holder
04464 )
04465 {
04466 term_t term;
04467 atom_t a;
04468 jstring string;
04469
04470 return jpl_ensure_pvm_init(env)
04471 && jstring_holder != NULL
04472 && getLongValue(env,jterm,(long*)&term)
04473 && PL_get_atom(term,&a)
04474 && jni_atom_to_String(env,a,&string)
04475 && setStringValue(env,jstring_holder,string)
04476 ;
04477 }
04478
04479
04480
04481
04482
04483
04484
04485 JNIEXPORT jobject JNICALL
04486 Java_jpl_fli_Prolog_get_1c_1lib_1version(
04487 JNIEnv *env,
04488 jclass jProlog
04489 )
04490 {
04491
04492 return (*env)->NewStringUTF(env,JPL_C_LIB_VERSION);
04493 }
04494
04495
04496
04497
04498
04499
04500
04501 JNIEXPORT jboolean JNICALL
04502 Java_jpl_fli_Prolog_get_1float(
04503 JNIEnv *env,
04504 jclass jProlog,
04505 jobject jterm,
04506 jobject jdouble_holder
04507 )
04508 {
04509 term_t term;
04510 double d;
04511
04512 return jpl_ensure_pvm_init(env)
04513 && jdouble_holder != NULL
04514 && getLongValue(env,jterm,(long*)&term)
04515 && PL_get_float(term,&d)
04516 && setDoubleValue(env,jdouble_holder,d)
04517 ;
04518 }
04519
04520
04521
04522
04523
04524
04525
04526 JNIEXPORT jboolean JNICALL
04527 Java_jpl_fli_Prolog_get_1integer(
04528 JNIEnv *env,
04529 jclass jProlog,
04530 jobject jterm,
04531 jobject jint64_holder
04532 )
04533 {
04534 term_t term;
04535 int64_t i64;
04536
04537 return jpl_ensure_pvm_init(env)
04538 && jint64_holder != NULL
04539 && getLongValue(env,jterm,(long*)&term)
04540 && PL_get_int64(term,&i64)
04541 && setLongValue(env,jint64_holder,i64)
04542 ;
04543 }
04544
04545
04546
04547
04548
04549
04550
04551 JNIEXPORT jboolean JNICALL
04552 Java_jpl_fli_Prolog_get_1name_1arity(
04553 JNIEnv *env,
04554 jclass jProlog,
04555 jobject jterm,
04556 jobject jname_holder,
04557 jobject jarity_holder
04558 )
04559 {
04560 term_t term;
04561 atom_t atom;
04562 jstring jname;
04563 int arity;
04564
04565 return jpl_ensure_pvm_init(env)
04566 && jname_holder != NULL
04567 && jarity_holder != NULL
04568 && getLongValue(env,jterm,(long*)&term)
04569 && PL_get_name_arity(term,&atom,&arity)
04570 && jni_atom_to_String(env,atom,&jname)
04571 && setStringValue(env,jname_holder,jname)
04572 && setIntValue(env,jarity_holder,arity)
04573 ;
04574 }
04575
04576
04577
04578
04579
04580
04581
04582 JNIEXPORT jboolean JNICALL
04583 Java_jpl_fli_Prolog_get_1string_1chars(
04584 JNIEnv *env,
04585 jclass jProlog,
04586 jobject jterm,
04587 jobject jstring_holder
04588 )
04589 {
04590 term_t term;
04591 jstring string;
04592
04593 return jpl_ensure_pvm_init(env)
04594 && jstring_holder != NULL
04595 && getLongValue(env,jterm,(long*)&term)
04596 && jni_string_to_String(env,term,&string)
04597 && setStringValue(env,jstring_holder,string)
04598 ;
04599 }
04600
04601
04602
04603
04604
04605
04606
04607 JNIEXPORT jobject JNICALL
04608 Java_jpl_fli_Prolog_new_1atom(
04609 JNIEnv *env,
04610 jclass jProlog,
04611 jstring jname
04612 )
04613 {
04614 atom_t atom;
04615 jobject rval;
04616
04617 return ( jpl_ensure_pvm_init(env)
04618 && jname != NULL
04619 && jni_String_to_atom(env,jname,&atom)
04620 && (rval=(*env)->AllocObject(env,jAtomT_c)) != NULL
04621 && setLongValue(env,rval,(long)atom)
04622 ? rval
04623 : NULL
04624 )
04625 ;
04626 }
04627
04628
04629
04630
04631
04632
04633
04634 JNIEXPORT jobject JNICALL
04635 Java_jpl_fli_Prolog_new_1functor(
04636 JNIEnv *env,
04637 jclass jProlog,
04638 jobject jatom,
04639 jint jarity
04640 )
04641 {
04642 term_t atom;
04643 functor_t functor;
04644 jobject rval;
04645
04646 return ( jpl_ensure_pvm_init(env)
04647 && jarity >= 0
04648 && getLongValue(env,jatom,(long*)&atom)
04649 && (rval=(*env)->AllocObject(env,jFunctorT_c)) != NULL
04650 && (functor=PL_new_functor(atom,(int)jarity)) != 0L
04651 && setLongValue(env,rval,(long)functor)
04652 ? rval
04653 : NULL
04654 )
04655 ;
04656 }
04657
04658
04659
04660
04661
04662
04663
04664 JNIEXPORT jobject JNICALL
04665 Java_jpl_fli_Prolog_new_1module(
04666 JNIEnv *env,
04667 jclass jProlog,
04668 jobject jatom
04669 )
04670 {
04671 atom_t atom;
04672 module_t module;
04673 jobject rval;
04674
04675 return ( jpl_ensure_pvm_init(env)
04676 && getLongValue(env,jatom,(long*)&atom)
04677 && ( (module=PL_new_module(atom)) , TRUE )
04678 && (rval=(*env)->AllocObject(env,jModuleT_c)) != NULL
04679 && setPointerValue(env,rval,(pointer)module)
04680 ? rval
04681 : NULL
04682 )
04683 ;
04684 }
04685
04686
04687
04688
04689
04690
04691
04692 JNIEXPORT jobject JNICALL
04693 Java_jpl_fli_Prolog_new_1term_1ref(
04694 JNIEnv *env,
04695 jclass jProlog
04696 )
04697 {
04698 jobject rval;
04699
04700 return ( jpl_ensure_pvm_init(env)
04701 && (rval=(*env)->AllocObject(env,jTermT_c)) != NULL
04702 && setLongValue(env,rval,(long)PL_new_term_ref())
04703 ? rval
04704 : NULL
04705 )
04706 ;
04707 }
04708
04709
04710
04711
04712
04713
04714
04715 JNIEXPORT jobject JNICALL
04716 Java_jpl_fli_Prolog_new_1term_1refs(
04717 JNIEnv *env,
04718 jclass jProlog,
04719 jint jn
04720 )
04721 {
04722 jobject rval;
04723 term_t trefs;
04724
04725 DEBUG(1, Sdprintf( ">new_term_refs(env=%lu,jProlog=%lu,jn=%lu)...\n", (long)env, (long)jProlog, (long)jn));
04726
04727 return ( jpl_ensure_pvm_init(env)
04728 && jn >= 0
04729 && (rval=(*env)->AllocObject(env,jTermT_c)) != NULL
04730 && ( trefs=PL_new_term_refs((int)jn), TRUE )
04731 && setLongValue(env,rval,(long)trefs)
04732 && ( DEBUG(1, Sdprintf(" ok: stashed trefs=%ld into new term_t object\n",(long)trefs)), TRUE )
04733 ? rval
04734 : NULL
04735 )
04736 ;
04737 }
04738
04739
04740
04741
04742
04743
04744
04745 JNIEXPORT jboolean JNICALL
04746 Java_jpl_fli_Prolog_next_1solution(
04747 JNIEnv *env,
04748 jclass jProlog,
04749 jobject jqid
04750 )
04751 {
04752 qid_t qid;
04753 int rval;
04754
04755 DEBUG(1, Sdprintf( ">next_solution(env=%lu,jProlog=%lu,jqid=%lu)...\n", (long)env, (long)jProlog, (long)jqid));
04756 return jpl_ensure_pvm_init(env)
04757 && getLongValue(env,jqid,(long*)&qid)
04758 && ( DEBUG(1, Sdprintf( " ok: getLongValue(env,jqid,(long*)&qid(%lu))\n",(long)qid)), TRUE )
04759 && ( rval=PL_next_solution(qid), TRUE )
04760 && ( DEBUG(1, Sdprintf( " ok: PL_next_solution(qid=%lu)=%u\n",(long)qid,rval)), TRUE )
04761 && (
04762 DEBUG(1, Sdprintf(" =%lu\n",(long)rval)),
04763 rval
04764 )
04765 ;
04766 }
04767
04768
04769
04770
04771
04772
04773
04774 JNIEXPORT jobject JNICALL
04775 Java_jpl_fli_Prolog_object_1to_1tag(
04776 JNIEnv *env,
04777 jclass jProlog,
04778 jobject jobj
04779 )
04780 {
04781 intptr_t iref;
04782 char abuf[23];
04783
04784
04785
04786
04787
04788
04789 if ( !jpl_ensure_pvm_init(env) ) {
04790
04791 return NULL;
04792 }
04793
04794
04795 if ( !jni_ensure_jvm() ) {
04796
04797 return NULL;
04798 }
04799
04800
04801 if ( jobj!=NULL && jni_object_to_iref(env,jobj,&iref) ) {
04802
04803 sprintf( abuf, IREF_FMT, (IREF_INTTYPE)iref);
04804
04805 return (*env)->NewStringUTF(env,abuf);
04806 } else {
04807 return NULL;
04808 }
04809 }
04810
04811
04812
04813
04814
04815
04816
04817 JNIEXPORT jobject JNICALL
04818 Java_jpl_fli_Prolog_open_1query(
04819 JNIEnv *env,
04820 jclass jProlog,
04821 jobject jmodule,
04822 jint jflags,
04823 jobject jpredicate,
04824 jobject jterm0
04825 )
04826 {
04827 module_t module;
04828 predicate_t predicate;
04829 term_t term0;
04830 qid_t qid;
04831 jobject jqid;
04832
04833 DEBUG(1, Sdprintf( ">open_query(env=%lu,jProlog=%lu,jmodule=%lu,jflags=%lu,jpredicate=%lu,jterm0=%lu)...\n",
04834 (long)env, (long)jProlog, (long)jmodule, (long)jflags, (long)jpredicate, (long)jterm0));
04835 return ( jpl_ensure_pvm_init(env)
04836 && ( getPointerValue(env,jmodule,(pointer*)&module) , TRUE )
04837 && ( DEBUG(1, Sdprintf(" ok: getPointerValue(env,jmodule=%lu,&(pointer)module=%lu)\n",(long)jmodule,(long)module)), TRUE )
04838 && getPointerValue(env,jpredicate,(pointer*)&predicate)
04839 && ( DEBUG(1, Sdprintf(" ok: getPointerValue(env,jpredicate=%lu,&(pointer)predicate=%lu)\n",(long)jpredicate,(long)predicate)), TRUE )
04840 && getLongValue(env,jterm0,(long*)&term0)
04841 && ( (qid=PL_open_query(module,jflags,predicate,term0)) , TRUE )
04842 && ( DEBUG(1, Sdprintf(" ok: PL_open_query(module=%lu,jflags=%u,predicate=%lu,term0=%lu)=%lu\n",(long)module,jflags,(long)predicate,(long)term0,(long)qid)), TRUE )
04843 && (jqid=(*env)->AllocObject(env,jQidT_c)) != NULL
04844 && ( DEBUG(1, Sdprintf(" ok: AllocObject(env,jQidT_c)=%lu\n",(long)jqid)), TRUE )
04845 && setLongValue(env,jqid,(long)qid)
04846 && ( DEBUG(1, Sdprintf(" ok: setLongValue(env,%lu,%lu)\n",(long)jqid,(long)qid)), TRUE )
04847 && ( DEBUG(1, Sdprintf("[open_query module = %s]\n", (module==NULL?"(null)":PL_atom_chars(PL_module_name(module))))), TRUE )
04848 ? (
04849 DEBUG(1, Sdprintf(" =%lu\n",(long)jqid)),
04850 jqid
04851 )
04852 : NULL
04853 )
04854 ;
04855 }
04856
04857
04858
04859
04860
04861
04862
04863 JNIEXPORT jobject JNICALL
04864 Java_jpl_fli_Prolog_predicate(
04865 JNIEnv *env,
04866 jclass jProlog,
04867 jstring jname,
04868 jint jarity,
04869 jstring jmodule
04870 )
04871 {
04872 atom_t pname;
04873 atom_t mname;
04874 functor_t func;
04875 module_t mod;
04876 predicate_t predicate;
04877 jobject rval;
04878
04879 DEBUG(1, Sdprintf(">predicate(env=%lu,jProlog=%lu,jname=%lu,jarity=%lu,jmodule=%lu)...\n",
04880 (long)env, (long)jProlog, (long)jname, (long)jarity, (long)jmodule));
04881 return ( jpl_ensure_pvm_init(env)
04882 && jni_String_to_atom(env,jname,&pname)
04883 && jarity >= 0
04884 && ( func=PL_new_functor(pname,jarity) , TRUE )
04885 && ( jmodule != NULL
04886 ? jni_String_to_atom(env,jmodule,&mname)
04887 : ( mname=(atom_t)NULL , TRUE )
04888 )
04889 && ( mod=PL_new_module(mname) , TRUE)
04890 && ( predicate=PL_pred(func,mod) , TRUE )
04891 && (rval=(*env)->AllocObject(env,jPredicateT_c)) != NULL
04892 && setPointerValue(env,rval,(pointer)predicate)
04893 ? (
04894 DEBUG(1, Sdprintf("[predicate() module=%s\n",(jmodule==NULL?"(null)":PL_atom_chars(mname)))),
04895 rval
04896 )
04897 : NULL
04898 )
04899 ;
04900 }
04901
04902
04903
04904
04905
04906
04907
04908 JNIEXPORT void JNICALL
04909 Java_jpl_fli_Prolog_put_1float(
04910 JNIEnv *env,
04911 jclass jProlog,
04912 jobject jterm,
04913 jdouble jf
04914 )
04915 {
04916 term_t term;
04917
04918 if ( jpl_ensure_pvm_init(env)
04919 && getLongValue(env,jterm,(long*)&term)
04920 )
04921 {
04922 PL_put_float( term, jf);
04923 }
04924 }
04925
04926
04927
04928
04929
04930
04931
04932 JNIEXPORT void JNICALL
04933 Java_jpl_fli_Prolog_put_1integer(
04934 JNIEnv *env,
04935 jclass jProlog,
04936 jobject jterm,
04937 jlong ji
04938 )
04939 {
04940 term_t term;
04941
04942 if ( jpl_ensure_pvm_init(env)
04943 && getLongValue(env,jterm,(long*)&term)
04944 )
04945 {
04946 PL_put_integer( term, (int)ji);
04947 }
04948 }
04949
04950
04951
04952
04953
04954
04955
04956 JNIEXPORT void JNICALL
04957 Java_jpl_fli_Prolog_put_1term(
04958 JNIEnv *env,
04959 jclass jProlog,
04960 jobject jterm1,
04961 jobject jterm2
04962 )
04963 {
04964 term_t term1;
04965 term_t term2;
04966
04967 if ( jpl_ensure_pvm_init(env)
04968 && getLongValue(env,jterm1,(long*)&term1)
04969 && getLongValue(env,jterm2,(long*)&term2)
04970 )
04971 {
04972 PL_put_term( term1, term2);
04973 }
04974 }
04975
04976
04977
04978
04979
04980
04981
04982
04983 JNIEXPORT void JNICALL
04984 Java_jpl_fli_Prolog_put_1jref(
04985 JNIEnv *env,
04986 jclass jProlog,
04987 jobject jterm,
04988 jobject jref
04989 )
04990 {
04991 term_t term;
04992 jobject j;
04993 atom_t a;
04994 intptr_t i;
04995
04996 if ( jpl_ensure_pvm_init(env)
04997 && jni_ensure_jvm()
04998 && getLongValue(env,jterm,(long*)&term)
04999 )
05000 {
05001 JNI_jobject_to_term(jref,term);
05002 }
05003 }
05004
05005
05006
05007
05008
05009
05010
05011
05012 JNIEXPORT jobject JNICALL
05013 Java_jpl_fli_Prolog_tag_1to_1object(
05014 JNIEnv *env,
05015 jclass jProlog,
05016 jstring tag
05017 )
05018 {
05019 jobject jobj;
05020
05021 if ( jni_ensure_jvm()
05022 && (*env)->GetStringLength(env,tag) == 22
05023 )
05024 {
05025 jni_tag_to_iref2((char*)(*env)->GetStringUTFChars(env,tag,0), (pointer *)&jobj);
05026 return jobj;
05027 }
05028 return 0;
05029 }
05030
05031
05032
05033
05034
05035
05036
05037 JNIEXPORT jboolean JNICALL
05038 Java_jpl_fli_Prolog_is_1tag(
05039 JNIEnv *env,
05040 jclass jProlog,
05041 jstring tag
05042 )
05043 {
05044 jobject jobj;
05045
05046 if ( jni_ensure_jvm()
05047 && (*env)->GetStringLength(env,tag) == 22
05048 )
05049 {
05050 jni_tag_to_iref2((char*)(*env)->GetStringUTFChars(env,tag,0), (pointer *)&jobj);
05051 return jobj != 0;
05052 }
05053
05054 return 0;
05055 }
05056
05057
05058
05059
05060
05061
05062
05063 JNIEXPORT void JNICALL
05064 Java_jpl_fli_Prolog_put_1variable(
05065 JNIEnv *env,
05066 jclass jProlog,
05067 jobject jterm
05068 )
05069 {
05070 term_t term;
05071
05072 if ( jpl_ensure_pvm_init(env)
05073 && getLongValue(env,jterm,(long*)&term)
05074 )
05075 {
05076 PL_put_variable(term);
05077 }
05078 }
05079
05080
05081
05082
05083
05084
05085
05086 JNIEXPORT jint JNICALL
05087 Java_jpl_fli_Prolog_term_1type(
05088 JNIEnv *env,
05089 jclass jProlog,
05090 jobject jterm
05091 )
05092 {
05093 term_t term;
05094
05095 return ( jpl_ensure_pvm_init(env)
05096 && getLongValue(env,jterm,(long*)&term)
05097 ? PL_term_type(term)
05098 : -1
05099 )
05100 ;
05101 }
05102
05103
05104
05105
05106
05107
05108
05109 JNIEXPORT void JNICALL
05110 Java_jpl_fli_Prolog_unregister_1atom(
05111 JNIEnv *env,
05112 jclass jProlog,
05113 jobject jatom
05114 )
05115 {
05116 atom_t atom;
05117
05118 DEBUG(1, Sdprintf( ">unregister_atom(env=%lu,jProlog=%lu,jatom=%u)...\n", (long)env, (long)jProlog, (long)jatom));
05119
05120 if ( jpl_ensure_pvm_init(env)
05121 && getLongValue(env,jatom,(long*)&atom)
05122 )
05123 {
05124 PL_unregister_atom( atom);
05125 DEBUG(1, Sdprintf( " ok: PL_unregister_atom(%lu)\n", (long)atom));
05126 }
05127 }
05128
05129
05130
05131
05132
05133
05134
05135 JNIEXPORT jobject JNICALL
05136 Java_jpl_fli_Prolog_open_1foreign_1frame(
05137 JNIEnv *env,
05138 jclass jProlog
05139 )
05140 {
05141 jobject rval;
05142
05143 if ( jpl_ensure_pvm_init(env)
05144 && (rval=(*env)->AllocObject(env,jFidT_c)) != NULL
05145 && setLongValue(env,rval,(long)PL_open_foreign_frame())
05146 )
05147 {
05148 return rval;
05149 }
05150 else
05151 {
05152 return NULL;
05153 }
05154 }
05155
05156
05157
05158
05159
05160
05161
05162 JNIEXPORT void JNICALL
05163 Java_jpl_fli_Prolog_discard_1foreign_1frame(
05164 JNIEnv *env,
05165 jclass jProlog,
05166 jobject jfid
05167 )
05168 {
05169 fid_t fid;
05170
05171 if ( jpl_ensure_pvm_init(env)
05172 && getLongValue(env,jfid,(long*)&fid)
05173 )
05174 {
05175 PL_discard_foreign_frame(fid);
05176 }
05177 }
05178
05179
05180
05181
05182
05183
05184
05185
05186
05187 JNIEXPORT jint JNICALL
05188 Java_jpl_fli_Prolog_thread_1self(
05189 JNIEnv *env,
05190 jclass jProlog
05191 )
05192 {
05193
05194 if ( jpl_ensure_pvm_init(env) )
05195 {
05196 return PL_thread_self();
05197 }
05198 else
05199 {
05200 return -2;
05201 }
05202 }
05203
05204
05205 static int
05206 create_pool_engines()
05207 {
05208 int i;
05209
05210 DEBUG(1, Sdprintf( "JPL creating engine pool:\n"));
05211 if ( (engines=malloc(sizeof(PL_engine_t)*JPL_MAX_POOL_ENGINES)) == NULL )
05212 {
05213 return -1;
05214 }
05215 engines_allocated = JPL_MAX_POOL_ENGINES;
05216 memset(engines, 0, sizeof(PL_engine_t)*engines_allocated);
05217
05218 DEBUG(1, Sdprintf( "JPL stashing default engine as [0]\n"));
05219 PL_set_engine( PL_ENGINE_CURRENT, &engines[0]);
05220
05221 DEBUG(1, Sdprintf( "JPL detaching default engine\n"));
05222
05223
05224 for ( i=1 ; i<JPL_INITIAL_POOL_ENGINES ; i++ )
05225 {
05226 if ( (engines[i]=PL_create_engine(NULL)) == NULL )
05227 {
05228 return -2;
05229 }
05230 DEBUG(1, Sdprintf( "\tengine[%d]=%p created\n", i, engines[i]));
05231 }
05232 return 0;
05233 }
05234
05235
05236
05237
05238
05239
05240
05241 JNIEXPORT jobject JNICALL
05242 Java_jpl_fli_Prolog_attach_1pool_1engine(
05243 JNIEnv *env,
05244 jclass jProlog
05245 )
05246 {
05247 jobject rval;
05248 int i;
05249
05250 if ( !jpl_ensure_pvm_init(env) )
05251 {
05252 return NULL;
05253 }
05254
05255
05256
05257 pthread_mutex_lock( &engines_mutex);
05258 for ( ; ; )
05259 {
05260 try_again:
05261 for ( i=0 ; i<engines_allocated ; i++ )
05262 {
05263 int rc;
05264
05265 if ( !engines[i] )
05266 continue;
05267
05268 if ( (rc=PL_set_engine(engines[i],NULL)) == PL_ENGINE_SET )
05269 {
05270 DEBUG(1, Sdprintf( "JPL attaching engine[%d]=%p\n", i, engines[i]));
05271 pthread_mutex_unlock( &engines_mutex);
05272 return ( (rval=(*env)->AllocObject(env,jEngineT_c)) != NULL
05273 && setPointerValue(env,rval,(pointer)engines[i])
05274 ? rval
05275 : NULL
05276 );
05277 }
05278 if ( rc != PL_ENGINE_INUSE )
05279 {
05280 DEBUG(1, Sdprintf( "JPL PL_set_engine fails with %d\n", rc));
05281 pthread_mutex_unlock( &engines_mutex);
05282 return NULL;
05283 }
05284 }
05285
05286 for ( i=0 ; i<engines_allocated ; i++ )
05287 { if ( !engines[i] )
05288 { DEBUG(1, Sdprintf("JPL no engines ready; creating new one\n"));
05289 if ( (engines[i]=PL_create_engine(NULL)) == NULL )
05290 { Sdprintf("JPL: Failed to create engine %d\n", i);
05291 return NULL;
05292 }
05293 goto try_again;
05294 }
05295 }
05296
05297 DEBUG(1, Sdprintf("JPL no engines ready; waiting...\n"));
05298 while( pthread_cond_wait(&engines_cond,&engines_mutex) == EINTR )
05299 {
05300 ;
05301 }
05302 }
05303 return NULL;
05304 }
05305
05306
05307
05308 static int
05309 pool_engine_id(
05310 PL_engine_t e
05311 )
05312 {
05313 int i;
05314
05315 for ( i=0 ; i<engines_allocated ; i++ )
05316 {
05317 if ( engines[i] && engines[i] == e )
05318 {
05319 DEBUG(1, Sdprintf( "JPL current pool engine[%d] = %p (thread_self = %d)\n", i, e, PL_thread_self()));
05320 return i;
05321 }
05322 }
05323 DEBUG(1, Sdprintf( "JPL current non-pool engine = %p (thread_self = %d)\n", e, PL_thread_self()));
05324 return -1;
05325 }
05326
05327
05328
05329 static int
05330 current_pool_engine_handle(
05331 PL_engine_t *e
05332 )
05333 {
05334
05335 PL_set_engine( PL_ENGINE_CURRENT, e);
05336 return pool_engine_id( *e);
05337 }
05338
05339
05340
05341 static int
05342 current_pool_engine()
05343 {
05344 PL_engine_t e;
05345
05346 return current_pool_engine_handle(&e);
05347 }
05348
05349
05350
05351
05352
05353
05354
05355
05356 JNIEXPORT int JNICALL
05357 Java_jpl_fli_Prolog_pool_1engine_1id(
05358 JNIEnv *env,
05359 jclass jProlog,
05360 jobject jengine
05361 )
05362 {
05363 PL_engine_t engine;
05364
05365 if ( !jpl_ensure_pvm_init(env) )
05366 {
05367 return -2;
05368 }
05369 if ( !getPointerValue(env,jengine,(intptr_t*)&engine) )
05370 {
05371 return -3;
05372 }
05373 return pool_engine_id(engine);
05374 }
05375
05376
05377
05378
05379
05380
05381
05382 JNIEXPORT int JNICALL
05383 Java_jpl_fli_Prolog_release_1pool_1engine(
05384 JNIEnv *env,
05385 jclass jProlog
05386 )
05387 {
05388
05389
05390
05391
05392 if ( jpl_ensure_pvm_init(env) )
05393 {
05394 int i;
05395 PL_engine_t e;
05396
05397 i = current_pool_engine_handle(&e);
05398 if ( i > 0 )
05399 { DEBUG(1, Sdprintf("JPL releasing engine[%d]=%p\n", i, e));
05400 PL_set_engine(NULL, NULL);
05401 pthread_cond_signal(&engines_cond);
05402 }
05403 return i;
05404 }
05405 else
05406 {
05407 return -2;
05408 }
05409 }
05410
05411
05412 static foreign_t
05413 jni_term_to_jref_plc(
05414 term_t tref1,
05415 term_t tref2
05416 )
05417 {
05418 jobject term1;
05419 atom_t a;
05420 intptr_t i;
05421 jobject j;
05422 JNIEnv *env;
05423
05424 return jni_ensure_jvm()
05425 && jpl_ensure_pvm_init(env)
05426 && (term1=(*env)->AllocObject(env,termt_class)) != NULL
05427 && setLongValue(env,term1,(long)tref1)
05428 && JNI_jobject_to_term((*env)->CallStaticObjectMethod(env,term_class,term_getTerm,term1),tref2)
05429 && jni_check_exception(env);
05430 }
05431
05432
05433
05434 static bool
05435 jni_jobject_to_term_byval(
05436 JNIEnv *env,
05437 jobject jobj,
05438 term_t term
05439 )
05440 {
05441 jobject termt;
05442
05443 return
05444 (termt=(*env)->AllocObject(env,termt_class)) != NULL
05445 && setLongValue(env,termt,(long)term)
05446 && ( (*env)->CallStaticVoidMethod(env,term_class,term_putTerm,jobj,termt) , TRUE )
05447 && jni_check_exception(env)
05448 ;
05449 }
05450
05451
05452
05453
05454 static foreign_t
05455 jni_jref_to_term_plc(
05456 term_t jref,
05457 term_t termIn
05458 )
05459 {
05460 functor_t fn;
05461 term_t arg = PL_new_term_ref();
05462 atom_t a;
05463 intptr_t iterm;
05464 jobject jterm;
05465 term_t term = PL_new_term_ref();
05466 JNIEnv *env;
05467
05468 return jni_ensure_jvm()
05469 && jpl_ensure_pvm_init(env)
05470 && PL_get_functor(jref,&fn)
05471 && fn==JNI_functor_at_1
05472 && PL_get_arg(1,jref,arg)
05473 && PL_get_atom(arg,&a)
05474 && jni_tag_to_iref(a,&iterm)
05475 && (jterm = (jobject)iterm)
05476 && jni_jobject_to_term_byval(env,jterm,term)
05477 && PL_unify( termIn, term)
05478 ;
05479 }
05480
05481
05482 static bool
05483 jni_get_default_jvm_opts_1(
05484 term_t args,
05485 int i,
05486 char **jvm_xia
05487 )
05488 {
05489 term_t tp = PL_new_term_ref();
05490
05491 if ( jvm_xia[i] == NULL )
05492 {
05493 return PL_unify_nil(args);
05494 }
05495 else
05496 {
05497 return PL_unify_list(args,tp,args)
05498 && PL_unify_term(tp,
05499 PL_ATOM, PL_new_atom(jvm_xia[i])
05500 )
05501 && jni_get_default_jvm_opts_1(args,i+1,jvm_xia)
05502 ;
05503 }
05504 }
05505
05506
05507 static foreign_t
05508 jni_get_jvm_opts(
05509 term_t args,
05510 char **jvm_xia
05511 )
05512 {
05513
05514 if ( jvm_xia==NULL )
05515 {
05516 return FALSE;
05517 }
05518 else
05519 {
05520 return jni_get_default_jvm_opts_1(args,0,jvm_xia);
05521 }
05522 }
05523
05524
05525 static foreign_t
05526 jni_set_default_jvm_opts_plc(
05527 term_t tn,
05528 term_t args
05529 )
05530 {
05531 int n;
05532 int i;
05533 term_t head;
05534 term_t list;
05535 char *s;
05536
05537 if ( jvm_dia == NULL )
05538 {
05539 return FALSE;
05540 }
05541 if ( !PL_get_integer(tn,&n) )
05542 {
05543 return FALSE;
05544 }
05545 if ( jvm_dia == jvm_ia )
05546 {
05547 DEBUG(1, Sdprintf("JPL not freeing original (static) JVM opts; replacing with malloc-ed [%d+1]\n", n));
05548 jvm_dia = (char**)malloc((n+1)*sizeof(char**));
05549 }
05550 else
05551 {
05552 DEBUG(1, Sdprintf("JPL has malloc-ed JVM opt[?] (of malloc-ed strings)\n"));
05553 for ( i = 0; jvm_dia[i] != NULL && i < 100; i++ )
05554 {
05555 DEBUG(1, Sdprintf("JPL freeing malloc-ed JVM opt '%s'\n", jvm_dia[i]));
05556 free(jvm_dia[i]);
05557 }
05558 if ( n != i )
05559 {
05560 DEBUG(1, Sdprintf("JPL needs different qty JVM opts so freeing old [%d] and malloc-ing new [%d]\n", i, n));
05561 free(jvm_dia);
05562 jvm_dia = (char**)malloc((n+1)*sizeof(char**));
05563 }
05564 else
05565 {
05566 DEBUG(1, Sdprintf("JPL needs [%d] JVM opts as before\n"));
05567 }
05568 }
05569 head = PL_new_term_ref();
05570 list = PL_copy_term_ref(args);
05571 for ( i = 0; PL_get_list(list,head,list); i++ )
05572 {
05573 if ( PL_get_atom_chars(head,&s) )
05574 {
05575 DEBUG(1, Sdprintf("JPL malloc-ing space for '%s'\n", s));
05576 jvm_dia[i] = (char*)malloc(strlen(s)+1);
05577 strcpy(jvm_dia[i],s);
05578 }
05579 else
05580 {
05581 return FALSE;
05582 }
05583 }
05584 jvm_dia[i] = NULL;
05585 return PL_get_nil(list);
05586 }
05587
05588
05589 static foreign_t
05590 jni_get_default_jvm_opts_plc(
05591 term_t args
05592 )
05593 {
05594
05595 return jni_get_jvm_opts(args,jvm_dia);
05596 }
05597
05598
05599 static foreign_t
05600 jni_get_actual_jvm_opts_plc(
05601 term_t args
05602 )
05603 {
05604
05605 return jni_get_jvm_opts(args,jvm_aia);
05606 }
05607
05608
05609
05610
05611 static
05612 PL_extension predspecs[] =
05613 { { "jni_get_created_jvm_count", 1, jni_get_created_jvm_count_plc, 0 },
05614 { "jni_ensure_jvm", 0, jni_ensure_jvm_plc, 0 },
05615 { "jni_tag_to_iref", 2, jni_tag_to_iref_plc, 0 },
05616 { "jni_hr_info", 4, jni_hr_info_plc, 0 },
05617 { "jni_hr_table", 1, jni_hr_table_plc, 0 },
05618 { "jni_byte_buf_length_to_codes", 3, jni_byte_buf_length_to_codes_plc, 0 },
05619 { "jni_param_put", 4, jni_param_put_plc, 0 },
05620 { "jni_alloc_buffer", 3, jni_alloc_buffer_plc, 0 },
05621 { "jni_free_buffer", 1, jni_free_buffer_plc, 0 },
05622 { "jni_fetch_buffer_value", 4, jni_fetch_buffer_value_plc, 0 },
05623 { "jni_stash_buffer_value", 4, jni_stash_buffer_value_plc, 0 },
05624 { "jni_void", 1, jni_void_0_plc, 0 },
05625 { "jni_void", 2, jni_void_1_plc, 0 },
05626 { "jni_void", 3, jni_void_2_plc, 0 },
05627 { "jni_void", 4, jni_void_3_plc, 0 },
05628 { "jni_void", 5, jni_void_4_plc, 0 },
05629 { "jni_func", 2, jni_func_0_plc, 0 },
05630 { "jni_func", 3, jni_func_1_plc, 0 },
05631 { "jni_func", 4, jni_func_2_plc, 0 },
05632 { "jni_func", 5, jni_func_3_plc, 0 },
05633 { "jni_func", 6, jni_func_4_plc, 0 },
05634 { "jpl_c_lib_version", 1, jpl_c_lib_version_1_plc, 0 },
05635 { "jpl_c_lib_version", 4, jpl_c_lib_version_4_plc, 0 },
05636 { "jni_term_to_jref", 2, jni_term_to_jref_plc, 0 },
05637 { "jni_jref_to_term", 2, jni_jref_to_term_plc, 0 },
05638 { "jni_get_default_jvm_opts", 1, jni_get_default_jvm_opts_plc, 0 },
05639 { "jni_set_default_jvm_opts", 2, jni_set_default_jvm_opts_plc, 0 },
05640 { "jni_get_actual_jvm_opts", 1, jni_get_actual_jvm_opts_plc, 0 },
05641 { NULL, 0, NULL, 0 }
05642 };
05643
05644
05645 install_t
05646 install()
05647 {
05648
05649 PL_register_extensions( predspecs);
05650 }
05651
05652
05653