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.

864 lines
22 KiB

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