You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

868 lines
22 KiB

25 years ago
25 years ago
25 years ago
26 years ago
25 years ago
26 years ago
25 years ago
26 years ago
25 years ago
26 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
26 years ago
26 years ago
25 years ago
25 years ago
26 years ago
25 years ago
25 years ago
26 years ago
26 years ago
26 years ago
25 years ago
26 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
26 years ago
25 years ago
25 years ago
25 years ago
26 years ago
25 years ago
26 years ago
26 years ago
26 years ago
25 years ago
26 years ago
26 years ago
25 years ago
25 years ago
26 years ago
26 years ago
26 years ago
25 years ago
25 years ago
26 years ago
26 years ago
26 years ago
25 years ago
25 years ago
26 years ago
26 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
26 years ago
26 years ago
25 years ago
26 years ago
25 years ago
25 years ago
25 years ago
26 years ago
26 years ago
26 years ago
25 years ago
25 years ago
25 years ago
26 years ago
26 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 4 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2002 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.02 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available at through the world-wide-web at |
  10. | http://www.php.net/license/2_02.txt. |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: Sam Ruby (rubys@us.ibm.com) |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id$ */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. /*
  23. * This module implements Zend OO syntax overloading support for Java
  24. * components using JNI and reflection.
  25. */
  26. #include "php.h"
  27. #include "zend_compile.h"
  28. #include "php_ini.h"
  29. #include "php_globals.h"
  30. #ifdef PHP_WIN32
  31. #include "win32/winutil.h"
  32. #define DL_ERROR php_win_err()
  33. #endif
  34. #include <jni.h>
  35. #include <stdio.h>
  36. #define IS_EXCEPTION 86
  37. /***************************************************************************/
  38. #ifndef KAFFE
  39. #ifndef JNI_11
  40. #ifndef JNI_12
  41. #ifdef JNI_VERSION_1_2
  42. #define JNI_12
  43. #else
  44. #define JNI_11
  45. #endif
  46. #endif
  47. #endif
  48. #endif
  49. #ifdef PHP_WIN32
  50. #ifdef JNI_12
  51. #define JAVALIB "jvm.dll"
  52. #else
  53. #define JAVALIB "javai.dll"
  54. #endif
  55. #else
  56. #endif
  57. /***************************************************************************/
  58. static int le_jobject = 0;
  59. static char *classpath = 0;
  60. static char *libpath = 0;
  61. static char *javahome = 0;
  62. static char *javalib = 0;
  63. static int iniUpdated = 0;
  64. static void *dl_handle = 0;
  65. /* {{{ ZEND_BEGIN_MODULE_GLOBALS
  66. */
  67. ZEND_BEGIN_MODULE_GLOBALS(java)
  68. JavaVM *jvm;
  69. JNIEnv *jenv;
  70. jobject php_reflect;
  71. jclass reflect_class;
  72. ZEND_END_MODULE_GLOBALS(java)
  73. /* }}} */
  74. #ifdef ZTS
  75. # define JG(v) TSRMG(java_globals_id, zend_java_globals *, v)
  76. #else
  77. # define JG(v) (java_globals.v)
  78. #endif
  79. ZEND_DECLARE_MODULE_GLOBALS(java)
  80. static zend_class_entry java_class_entry;
  81. static PHP_INI_MH(OnIniUpdate)
  82. {
  83. if (new_value) *(char**)mh_arg1 = new_value;
  84. iniUpdated=1;
  85. return SUCCESS;
  86. }
  87. /* {{{ PHP_INI_BEGIN
  88. */
  89. PHP_INI_BEGIN()
  90. PHP_INI_ENTRY1("java.class.path", NULL, PHP_INI_ALL, OnIniUpdate, &classpath)
  91. #ifndef JNI_11
  92. PHP_INI_ENTRY1("java.home", NULL, PHP_INI_ALL, OnIniUpdate, &javahome)
  93. PHP_INI_ENTRY1("java.library.path", NULL, PHP_INI_ALL, OnIniUpdate, &libpath)
  94. #endif
  95. #ifdef JAVALIB
  96. PHP_INI_ENTRY1("java.library", JAVALIB, PHP_INI_ALL, OnIniUpdate, &javalib)
  97. #else
  98. PHP_INI_ENTRY1("java.library", NULL, PHP_INI_ALL, OnIniUpdate, &javalib)
  99. #endif
  100. PHP_INI_END()
  101. /* }}} */
  102. /***************************************************************************/
  103. /* {{{ jvm_destroy
  104. */
  105. /*
  106. * Destroy a Java Virtual Machine.
  107. */
  108. void jvm_destroy(TSRMLS_D)
  109. {
  110. if (JG(php_reflect)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), JG(php_reflect));
  111. if (JG(jvm)) {
  112. (*JG(jvm))->DetachCurrentThread(JG(jvm));
  113. (*JG(jvm))->DestroyJavaVM(JG(jvm));
  114. JG(jvm) = 0;
  115. }
  116. if (dl_handle) DL_UNLOAD(dl_handle);
  117. JG(php_reflect) = 0;
  118. JG(jenv) = 0;
  119. }
  120. /* }}} */
  121. /* {{{ addJVMOption
  122. */
  123. /*
  124. * Create a Java Virtual Machine.
  125. * - class.path, home, and library.path are read out of the INI file
  126. * - appropriate (pre 1.1, JDK 1.1, and JDK 1.2) initialization is performed
  127. * - net.php.reflect class file is located
  128. */
  129. #ifdef JNI_12
  130. static void addJVMOption(JavaVMInitArgs *vm_args, char *name, char *value)
  131. {
  132. char *option = (char*) malloc(strlen(name) + strlen(value) + 1);
  133. strcpy(option, name);
  134. strcat(option, value);
  135. vm_args->options[vm_args->nOptions++].optionString = option;
  136. }
  137. #endif
  138. /* }}} */
  139. /* {{{ jvm_create
  140. */
  141. static int jvm_create(TSRMLS_D)
  142. {
  143. int rc;
  144. jobject local_php_reflect;
  145. jthrowable error;
  146. jint (JNICALL *JNI_CreateVM)(const void*, const void*, void*);
  147. #ifndef JNI_12
  148. jint (JNICALL *JNI_DefaultArgs)(void*);
  149. #endif
  150. #ifdef JNI_11
  151. JDK1_1InitArgs vm_args;
  152. #else
  153. JavaVMInitArgs vm_args;
  154. #ifdef JNI_12
  155. JavaVMOption options[3];
  156. #endif
  157. #endif
  158. iniUpdated=0;
  159. if (javalib) {
  160. dl_handle = DL_LOAD(javalib);
  161. if (!dl_handle) {
  162. php_error(E_ERROR, "Unable to load Java Library %s, error: %s",
  163. javalib, DL_ERROR);
  164. return -1;
  165. }
  166. }
  167. #ifndef JAVALIB
  168. if (!dl_handle)
  169. JNI_CreateVM = &JNI_CreateJavaVM;
  170. else
  171. #endif
  172. JNI_CreateVM = (jint (JNICALL *)(const void*, const void*, void*))
  173. DL_FETCH_SYMBOL(dl_handle, "JNI_CreateJavaVM");
  174. if (!JNI_CreateVM) {
  175. php_error(E_ERROR, "Unable to locate CreateJavaVM function");
  176. return -1;
  177. }
  178. #ifdef JNI_12
  179. vm_args.version = JNI_VERSION_1_2;
  180. vm_args.ignoreUnrecognized = JNI_FALSE;
  181. vm_args.options = options;
  182. vm_args.nOptions = 0;
  183. if (classpath) addJVMOption(&vm_args, "-Djava.class.path=", classpath);
  184. if (javahome) addJVMOption(&vm_args, "-Djava.home=", javahome);
  185. if (libpath) addJVMOption(&vm_args, "-Djava.library.path=", libpath);
  186. #else
  187. #ifndef JAVALIB
  188. if (!dl_handle)
  189. JNI_DefaultArgs = &JNI_GetDefaultJavaVMInitArgs;
  190. else
  191. #endif
  192. JNI_DefaultArgs = (jint (JNICALL *)(void*))
  193. DL_FETCH_SYMBOL(dl_handle, "JNI_GetDefaultJavaVMInitArgs");
  194. if (!JNI_DefaultArgs) {
  195. php_error(E_ERROR, "Unable to locate GetDefaultJavaVMInitArgs function");
  196. return -1;
  197. }
  198. vm_args.version=0x00010001;
  199. (*JNI_DefaultArgs)(&vm_args);
  200. if (!classpath) classpath = "";
  201. vm_args.classpath = classpath;
  202. #ifdef KAFFE
  203. vm_args.classhome = javahome;
  204. vm_args.libraryhome = libpath;
  205. #endif
  206. #endif
  207. rc = (*JNI_CreateVM)(&JG(jvm), &JG(jenv), &vm_args);
  208. if (rc) {
  209. php_error(E_ERROR, "Unable to create Java Virtual Machine");
  210. return rc;
  211. }
  212. JG(reflect_class) = (*JG(jenv))->FindClass(JG(jenv), "net/php/reflect");
  213. error = (*JG(jenv))->ExceptionOccurred(JG(jenv));
  214. if (error) {
  215. jclass errClass;
  216. jmethodID toString;
  217. jobject errString;
  218. const char *errAsUTF;
  219. jboolean isCopy;
  220. JNIEnv *jenv = JG(jenv);
  221. (*jenv)->ExceptionClear(jenv);
  222. errClass = (*jenv)->GetObjectClass(jenv, error);
  223. toString = (*jenv)->GetMethodID(jenv, errClass, "toString",
  224. "()Ljava/lang/String;");
  225. errString = (*jenv)->CallObjectMethod(jenv, error, toString);
  226. errAsUTF = (*jenv)->GetStringUTFChars(jenv, errString, &isCopy);
  227. php_error(E_ERROR, "%s", errAsUTF);
  228. if (isCopy) (*jenv)->ReleaseStringUTFChars(jenv, error, errAsUTF);
  229. jvm_destroy(TSRMLS_C);
  230. return -1;
  231. }
  232. local_php_reflect = (*JG(jenv))->AllocObject(JG(jenv), JG(reflect_class));
  233. JG(php_reflect) = (*JG(jenv))->NewGlobalRef(JG(jenv), local_php_reflect);
  234. return rc;
  235. }
  236. /* }}} */
  237. /***************************************************************************/
  238. /* {{{ _java_makeObject
  239. */
  240. static jobject _java_makeObject(pval* arg TSRMLS_DC)
  241. {
  242. JNIEnv *jenv = JG(jenv);
  243. jobject result;
  244. pval **handle;
  245. int type;
  246. jmethodID makeArg;
  247. jclass hashClass;
  248. switch (Z_TYPE_P(arg)) {
  249. case IS_STRING:
  250. result=(*jenv)->NewByteArray(jenv, Z_STRLEN_P(arg));
  251. (*jenv)->SetByteArrayRegion(jenv, (jbyteArray)result, 0,
  252. Z_STRLEN_P(arg), Z_STRVAL_P(arg));
  253. break;
  254. case IS_OBJECT:
  255. zend_hash_index_find(Z_OBJPROP_P(arg), 0, (void*)&handle);
  256. result = zend_list_find(Z_LVAL_PP(handle), &type);
  257. break;
  258. case IS_BOOL:
  259. makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",
  260. "(Z)Ljava/lang/Object;");
  261. result = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,
  262. (jboolean)(Z_LVAL_P(arg)));
  263. break;
  264. case IS_LONG:
  265. makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",
  266. "(J)Ljava/lang/Object;");
  267. result = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,
  268. (jlong)(Z_LVAL_P(arg)));
  269. break;
  270. case IS_DOUBLE:
  271. makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",
  272. "(D)Ljava/lang/Object;");
  273. result = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,
  274. (jdouble)(Z_DVAL_P(arg)));
  275. break;
  276. case IS_ARRAY:
  277. {
  278. jobject jkey, jval;
  279. zval **value;
  280. zval key;
  281. char *string_key;
  282. ulong num_key;
  283. jobject jold;
  284. jmethodID put, init;
  285. hashClass = (*jenv)->FindClass(jenv, "java/util/Hashtable");
  286. init = (*jenv)->GetMethodID(jenv, hashClass, "<init>", "()V");
  287. result = (*jenv)->NewObject(jenv, hashClass, init);
  288. put = (*jenv)->GetMethodID(jenv, hashClass, "put",
  289. "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
  290. /* Iterate through hash */
  291. zend_hash_internal_pointer_reset(Z_ARRVAL_P(arg));
  292. while(zend_hash_get_current_data(Z_ARRVAL_P(arg), (void**)&value) == SUCCESS) {
  293. jval = _java_makeObject(*value TSRMLS_CC);
  294. switch (zend_hash_get_current_key(Z_ARRVAL_P(arg), &string_key, &num_key, 0)) {
  295. case HASH_KEY_IS_STRING:
  296. Z_TYPE(key) = IS_STRING;
  297. Z_STRVAL(key) = string_key;
  298. Z_STRLEN(key) = strlen(string_key);
  299. jkey = _java_makeObject(&key TSRMLS_CC);
  300. break;
  301. case HASH_KEY_IS_LONG:
  302. Z_TYPE(key) = IS_LONG;
  303. Z_LVAL(key) = num_key;
  304. jkey = _java_makeObject(&key TSRMLS_CC);
  305. break;
  306. default: /* HASH_KEY_NON_EXISTANT */
  307. jkey = 0;
  308. }
  309. jold = (*jenv)->CallObjectMethod(jenv, result, put, jkey, jval);
  310. if (Z_TYPE_PP(value) != IS_OBJECT) (*jenv)->DeleteLocalRef(jenv, jval);
  311. zend_hash_move_forward(Z_ARRVAL_P(arg));
  312. }
  313. break;
  314. }
  315. default:
  316. result=0;
  317. }
  318. return result;
  319. }
  320. /* }}} */
  321. /***************************************************************************/
  322. /* {{{ _java_makeArray
  323. */
  324. static jobjectArray _java_makeArray(int argc, pval** argv TSRMLS_DC)
  325. {
  326. JNIEnv *jenv = JG(jenv);
  327. jclass objectClass = (*jenv)->FindClass(jenv, "java/lang/Object");
  328. jobjectArray result = (*jenv)->NewObjectArray(jenv, argc, objectClass, 0);
  329. jobject arg;
  330. int i;
  331. for (i=0; i<argc; i++) {
  332. arg = _java_makeObject(argv[i] TSRMLS_CC);
  333. (*jenv)->SetObjectArrayElement(jenv, result, i, arg);
  334. if (Z_TYPE_P(argv[i]) != IS_OBJECT) (*jenv)->DeleteLocalRef(jenv, arg);
  335. }
  336. return result;
  337. }
  338. /* }}} */
  339. /* {{{ checkError
  340. */
  341. static int checkError(pval *value)
  342. {
  343. if (Z_TYPE_P(value) == IS_EXCEPTION) {
  344. php_error(E_WARNING, "%s", Z_STRVAL_P(value));
  345. efree(Z_STRVAL_P(value));
  346. ZVAL_FALSE(value);
  347. return 1;
  348. };
  349. return 0;
  350. }
  351. /* }}} */
  352. /***************************************************************************/
  353. /* {{{ java_call_function_handler
  354. */
  355. /*
  356. * Invoke a method on an object. If method name is "java", create a new
  357. * object instead.
  358. */
  359. void java_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
  360. {
  361. JNIEnv *jenv;
  362. pval *object = property_reference->object;
  363. zend_overloaded_element *function_name = (zend_overloaded_element *)
  364. property_reference->elements_list->tail->data;
  365. int arg_count = ZEND_NUM_ARGS();
  366. jlong result = 0;
  367. pval **arguments = (pval **) emalloc(sizeof(pval *)*arg_count);
  368. getParametersArray(ht, arg_count, arguments);
  369. if (iniUpdated && JG(jenv)) jvm_destroy(TSRMLS_C);
  370. if (!JG(jenv)) jvm_create(TSRMLS_C);
  371. if (!JG(jenv)) return;
  372. jenv = JG(jenv);
  373. if (!strcmp("java", Z_STRVAL(function_name->element))) {
  374. /* construct a Java object:
  375. First argument is the class name. Any additional arguments will
  376. be treated as constructor parameters. */
  377. jmethodID co = (*jenv)->GetMethodID(jenv, JG(reflect_class), "CreateObject",
  378. "(Ljava/lang/String;[Ljava/lang/Object;J)V");
  379. jstring className;
  380. result = (jlong)(long)object;
  381. if (ZEND_NUM_ARGS() < 1) {
  382. php_error(E_ERROR, "Missing classname in new Java() call");
  383. return;
  384. }
  385. className=(*jenv)->NewStringUTF(jenv, Z_STRVAL_P(arguments[0]));
  386. (*jenv)->CallVoidMethod(jenv, JG(php_reflect), co,
  387. className, _java_makeArray(arg_count-1, arguments+1 TSRMLS_CC), result);
  388. (*jenv)->DeleteLocalRef(jenv, className);
  389. } else {
  390. pval **handle;
  391. int type;
  392. jobject obj;
  393. jstring method;
  394. /* invoke a method on the given object */
  395. jmethodID invoke = (*jenv)->GetMethodID(jenv, JG(reflect_class), "Invoke",
  396. "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V");
  397. zend_hash_index_find(Z_OBJPROP_P(object), 0, (void**) &handle);
  398. obj = zend_list_find(Z_LVAL_PP(handle), &type);
  399. method = (*jenv)->NewStringUTF(jenv, Z_STRVAL(function_name->element));
  400. result = (jlong)(long)return_value;
  401. (*jenv)->CallVoidMethod(jenv, JG(php_reflect), invoke,
  402. obj, method, _java_makeArray(arg_count, arguments TSRMLS_CC), result);
  403. (*jenv)->DeleteLocalRef(jenv, method);
  404. }
  405. efree(arguments);
  406. pval_destructor(&function_name->element);
  407. checkError((pval*)(long)result);
  408. }
  409. /* }}} */
  410. /***************************************************************************/
  411. /* {{{ proto object java_last_exception_get(void)
  412. Get last Java exception */
  413. PHP_FUNCTION(java_last_exception_get)
  414. {
  415. jlong result = 0;
  416. jmethodID lastEx;
  417. if (ZEND_NUM_ARGS()!=0) WRONG_PARAM_COUNT;
  418. result = (jlong)(long)return_value;
  419. lastEx = (*JG(jenv))->GetMethodID(JG(jenv), JG(reflect_class),
  420. "lastException", "(J)V");
  421. (*JG(jenv))->CallVoidMethod(JG(jenv), JG(php_reflect), lastEx, result);
  422. }
  423. /* }}} */
  424. /***************************************************************************/
  425. /* {{{ proto void java_last_exception_clear(void)
  426. Clear last java extension */
  427. PHP_FUNCTION(java_last_exception_clear)
  428. {
  429. jlong result = 0;
  430. jmethodID clearEx;
  431. if (ZEND_NUM_ARGS()!=0) WRONG_PARAM_COUNT;
  432. result = (jlong)(long)return_value;
  433. clearEx = (*JG(jenv))->GetMethodID(JG(jenv), JG(reflect_class),
  434. "clearException", "()V");
  435. (*JG(jenv))->CallVoidMethod(JG(jenv), JG(php_reflect), clearEx);
  436. }
  437. /* }}} */
  438. /***************************************************************************/
  439. /* {{{ _java_getset_property
  440. */
  441. static pval _java_getset_property
  442. (zend_property_reference *property_reference, jobjectArray value TSRMLS_DC)
  443. {
  444. pval presult;
  445. jlong result = 0;
  446. pval **pobject;
  447. jobject obj;
  448. int type;
  449. /* get the property name */
  450. zend_llist_element *element = property_reference->elements_list->head;
  451. zend_overloaded_element *property=(zend_overloaded_element *)element->data;
  452. jstring propName;
  453. JNIEnv *jenv;
  454. jenv = JG(jenv);
  455. propName = (*jenv)->NewStringUTF(jenv, Z_STRVAL(property->element));
  456. /* get the object */
  457. zend_hash_index_find(Z_OBJPROP_P(property_reference->object),
  458. 0, (void **) &pobject);
  459. obj = zend_list_find(Z_LVAL_PP(pobject), &type);
  460. result = (jlong)(long) &presult;
  461. Z_TYPE(presult) = IS_NULL;
  462. if (!obj || (type!=le_jobject)) {
  463. php_error(E_ERROR,
  464. "Attempt to access a Java property on a non-Java object");
  465. } else {
  466. /* invoke the method */
  467. jmethodID gsp = (*jenv)->GetMethodID(jenv, JG(reflect_class), "GetSetProp",
  468. "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V");
  469. (*jenv)->CallVoidMethod
  470. (jenv, JG(php_reflect), gsp, obj, propName, value, result);
  471. }
  472. (*jenv)->DeleteLocalRef(jenv, propName);
  473. pval_destructor(&property->element);
  474. return presult;
  475. }
  476. /* }}} */
  477. /* {{{ java_get_property_handler
  478. */
  479. pval java_get_property_handler(zend_property_reference *property_reference)
  480. {
  481. pval presult;
  482. TSRMLS_FETCH();
  483. presult = _java_getset_property(property_reference, 0 TSRMLS_CC);
  484. checkError(&presult);
  485. return presult;
  486. }
  487. /* }}} */
  488. /* {{{ java_set_property_handler
  489. */
  490. int java_set_property_handler(zend_property_reference *property_reference, pval *value)
  491. {
  492. pval presult;
  493. TSRMLS_FETCH();
  494. presult = _java_getset_property(property_reference, _java_makeArray(1, &value TSRMLS_CC) TSRMLS_CC);
  495. return checkError(&presult) ? FAILURE : SUCCESS;
  496. }
  497. /* }}} */
  498. /***************************************************************************/
  499. /* {{{ _php_java_destructor
  500. */
  501. static void _php_java_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  502. {
  503. void *jobject = (void *)rsrc->ptr;
  504. if (JG(jenv)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), jobject);
  505. }
  506. /* }}} */
  507. /* {{{ alloc_java_globals_ctor
  508. */
  509. static void alloc_java_globals_ctor(zend_java_globals *java_globals TSRMLS_DC)
  510. {
  511. memset(java_globals, 0, sizeof(zend_java_globals));
  512. }
  513. /* }}} */
  514. /* {{{ PHP_MINIT_FUNCTION
  515. */
  516. PHP_MINIT_FUNCTION(java)
  517. {
  518. INIT_OVERLOADED_CLASS_ENTRY(java_class_entry, "java", NULL,
  519. java_call_function_handler,
  520. java_get_property_handler,
  521. java_set_property_handler);
  522. zend_register_internal_class(&java_class_entry TSRMLS_CC);
  523. le_jobject = zend_register_list_destructors_ex(_php_java_destructor, NULL, "java", module_number);
  524. REGISTER_INI_ENTRIES();
  525. if (!classpath) classpath = getenv("CLASSPATH");
  526. if (!libpath) {
  527. libpath=PG(extension_dir);
  528. }
  529. ZEND_INIT_MODULE_GLOBALS(java, alloc_java_globals_ctor, NULL);
  530. return SUCCESS;
  531. }
  532. /* }}} */
  533. /* {{{ PHP_MSHUTDOWN_FUNCTION
  534. */
  535. PHP_MSHUTDOWN_FUNCTION(java)
  536. {
  537. UNREGISTER_INI_ENTRIES();
  538. if (JG(jvm)) jvm_destroy(TSRMLS_C);
  539. return SUCCESS;
  540. }
  541. /* }}} */
  542. function_entry java_functions[] = {
  543. PHP_FE(java_last_exception_get, NULL)
  544. PHP_FE(java_last_exception_clear, NULL)
  545. {NULL, NULL, NULL}
  546. };
  547. static PHP_MINFO_FUNCTION(java) {
  548. DISPLAY_INI_ENTRIES();
  549. }
  550. zend_module_entry java_module_entry = {
  551. STANDARD_MODULE_HEADER,
  552. "java",
  553. java_functions,
  554. PHP_MINIT(java),
  555. PHP_MSHUTDOWN(java),
  556. NULL,
  557. NULL,
  558. PHP_MINFO(java),
  559. NO_VERSION_YET,
  560. STANDARD_MODULE_PROPERTIES
  561. };
  562. ZEND_GET_MODULE(java)
  563. /***************************************************************************/
  564. /* {{{ Java_net_php_reflect_setResultFromString
  565. */
  566. JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromString
  567. (JNIEnv *jenv, jclass self, jlong result, jbyteArray jvalue)
  568. {
  569. jboolean isCopy;
  570. jbyte *value = (*jenv)->GetByteArrayElements(jenv, jvalue, &isCopy);
  571. pval *presult = (pval*)(long)result;
  572. Z_TYPE_P(presult)=IS_STRING;
  573. Z_STRLEN_P(presult)=(*jenv)->GetArrayLength(jenv, jvalue);
  574. Z_STRVAL_P(presult)=emalloc(Z_STRLEN_P(presult)+1);
  575. memcpy(Z_STRVAL_P(presult), value, Z_STRLEN_P(presult));
  576. Z_STRVAL_P(presult)[Z_STRLEN_P(presult)]=0;
  577. if (isCopy) (*jenv)->ReleaseByteArrayElements(jenv, jvalue, value, 0);
  578. }
  579. /* }}} */
  580. /* {{{ Java_net_php_reflect_setResultFromLong
  581. */
  582. JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromLong
  583. (JNIEnv *jenv, jclass self, jlong result, jlong value)
  584. {
  585. pval *presult = (pval*)(long)result;
  586. Z_TYPE_P(presult)=IS_LONG;
  587. Z_LVAL_P(presult)=(long)value;
  588. }
  589. /* }}} */
  590. /* {{{ Java_net_php_reflect_setResultFromDouble
  591. */
  592. JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromDouble
  593. (JNIEnv *jenv, jclass self, jlong result, jdouble value)
  594. {
  595. pval *presult = (pval*)(long)result;
  596. Z_TYPE_P(presult)=IS_DOUBLE;
  597. Z_DVAL_P(presult)=value;
  598. }
  599. /* }}} */
  600. /* {{{ Java_net_php_reflect_setResultFromBoolean
  601. */
  602. JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromBoolean
  603. (JNIEnv *jenv, jclass self, jlong result, jboolean value)
  604. {
  605. pval *presult = (pval*)(long)result;
  606. Z_TYPE_P(presult)=IS_BOOL;
  607. Z_LVAL_P(presult)=value;
  608. }
  609. /* }}} */
  610. /* {{{ Java_net_php_reflect_setResultFromObject
  611. */
  612. JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromObject
  613. (JNIEnv *jenv, jclass self, jlong result, jobject value)
  614. {
  615. /* wrapper the java object in a pval object */
  616. pval *presult = (pval*)(long)result;
  617. pval *handle;
  618. TSRMLS_FETCH();
  619. if (Z_TYPE_P(presult) != IS_OBJECT) {
  620. object_init_ex(presult, &java_class_entry);
  621. presult->is_ref=1;
  622. presult->refcount=1;
  623. }
  624. ALLOC_ZVAL(handle);
  625. Z_TYPE_P(handle) = IS_LONG;
  626. Z_LVAL_P(handle) =
  627. zend_list_insert((*jenv)->NewGlobalRef(jenv, value), le_jobject);
  628. pval_copy_constructor(handle);
  629. INIT_PZVAL(handle);
  630. zend_hash_index_update(Z_OBJPROP_P(presult), 0, &handle, sizeof(pval *), NULL);
  631. }
  632. /* }}} */
  633. /* {{{ Java_net_php_reflect_setResultFromArray
  634. */
  635. JNIEXPORT void JNICALL Java_net_php_reflect_setResultFromArray
  636. (JNIEnv *jenv, jclass self, jlong result)
  637. {
  638. array_init( (pval*)(long)result );
  639. }
  640. /* }}} */
  641. /* {{{ Java_net_php_reflect_nextElement
  642. */
  643. JNIEXPORT jlong JNICALL Java_net_php_reflect_nextElement
  644. (JNIEnv *jenv, jclass self, jlong array)
  645. {
  646. pval *result;
  647. pval *handle = (pval*)(long)array;
  648. ALLOC_ZVAL(result);
  649. zend_hash_next_index_insert(Z_ARRVAL_P(handle), &result, sizeof(zval *), NULL);
  650. return (jlong)(long)result;
  651. }
  652. /* }}} */
  653. /* {{{ Java_net_php_reflect_hashIndexUpdate
  654. */
  655. JNIEXPORT jlong JNICALL Java_net_php_reflect_hashIndexUpdate
  656. (JNIEnv *jenv, jclass self, jlong array, jlong key)
  657. {
  658. pval *result;
  659. pval *handle = (pval*)(long)array;
  660. ALLOC_ZVAL(result);
  661. zend_hash_index_update(Z_ARRVAL_P(handle), (unsigned long)key,
  662. &result, sizeof(zval *), NULL);
  663. return (jlong)(long)result;
  664. }
  665. /* }}} */
  666. /* {{{ Java_net_php_reflect_hashUpdate
  667. */
  668. JNIEXPORT jlong JNICALL Java_net_php_reflect_hashUpdate
  669. (JNIEnv *jenv, jclass self, jlong array, jbyteArray key)
  670. {
  671. pval *result;
  672. pval pkey;
  673. pval *handle = (pval*)(long)array;
  674. ALLOC_ZVAL(result);
  675. Java_net_php_reflect_setResultFromString(jenv, self, (jlong)(long)&pkey, key);
  676. zend_hash_update(Z_ARRVAL_P(handle), Z_STRVAL(pkey), Z_STRLEN(pkey)+1,
  677. &result, sizeof(zval *), NULL);
  678. return (jlong)(long)result;
  679. }
  680. /* }}} */
  681. /* {{{ Java_net_php_reflect_setException
  682. */
  683. JNIEXPORT void JNICALL Java_net_php_reflect_setException
  684. (JNIEnv *jenv, jclass self, jlong result, jbyteArray value)
  685. {
  686. pval *presult = (pval*)(long)result;
  687. Java_net_php_reflect_setResultFromString(jenv, self, result, value);
  688. Z_TYPE_P(presult)=IS_EXCEPTION;
  689. }
  690. /* }}} */
  691. /* {{{ Java_net_php_reflect_setEnv
  692. */
  693. JNIEXPORT void JNICALL Java_net_php_reflect_setEnv
  694. (JNIEnv *newJenv, jclass self TSRMLS_DC)
  695. {
  696. jobject local_php_reflect;
  697. iniUpdated=0;
  698. JG(jenv)=newJenv;
  699. if (!self) self = (*JG(jenv))->FindClass(JG(jenv), "net/php/reflect");
  700. JG(reflect_class) = self;
  701. if (JG(php_reflect)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), JG(php_reflect));
  702. local_php_reflect = (*JG(jenv))->AllocObject(JG(jenv), JG(reflect_class));
  703. JG(php_reflect) = (*JG(jenv))->NewGlobalRef(JG(jenv), local_php_reflect);
  704. }
  705. /* }}} */
  706. /*
  707. * Local variables:
  708. * tab-width: 4
  709. * c-basic-offset: 4
  710. * End:
  711. * vim600: sw=4 ts=4 fdm=marker
  712. * vim<600: sw=4 ts=4
  713. */