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.

876 lines
22 KiB

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