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.

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