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.

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