]> granicus.if.org Git - php/commitdiff
Reentrancy fixes
authorSam Ruby <rubys@php.net>
Sun, 9 Jul 2000 04:16:31 +0000 (04:16 +0000)
committerSam Ruby <rubys@php.net>
Sun, 9 Jul 2000 04:16:31 +0000 (04:16 +0000)
ext/java/README
ext/java/java.c
ext/java/reflect.java
ext/rpc/java/README
ext/rpc/java/java.c
ext/rpc/java/reflect.java

index 6c64dcfe400ec069ff6de8e01f6dd04d21a74a21..097bfabf1a304573e548c5e53e469135951e6a51 100644 (file)
@@ -22,14 +22,12 @@ What is PHP4 ext/java?
 
      4) Exceptions raised result in PHP warnings, and null results.  The
         warnings may be eliminated by prefixing the method call with an
-        "@" sign.  The following experimental APIs may be used to retrieve
-        and reset the last error:
+        "@" sign.  The following APIs may be used to retrieve and reset
+        the last error:
 
           java_last_exception_get()
           java_last_exception_clear()
 
-        These APIs are not currently implemented in a reentrant fashion.
-
      5) Overload resolution is in general a hard problem given the
         differences in types between the two languages.  The PHP Java
        extension employs a simple, but fairly effective, metric for
index 9d0cf7516e27c215b5415e4fffa630c98e819cfe..83db3d4b7aa7ed99213f29cdd7de70021fb47313 100644 (file)
@@ -68,12 +68,33 @@ static char *javahome  = 0;
 static char *javalib   = 0;
 
 static int iniUpdated  = 0;
-
-static JavaVM *jvm = 0;
-static JNIEnv *jenv = 0;
-static jclass php_reflect;
 static void *dl_handle = 0;
 
+typedef struct {
+  JavaVM *jvm;
+  JNIEnv *jenv;
+  jobject php_reflect;
+  jclass  reflect_class;
+} php_java_globals;
+
+#ifdef ZTS
+#define JG(v) (java_globals->v)
+#define JG_FETCH() php_java_globals *java_globals = ts_resource(java_globals_id)
+#define JG_D       php_java_globals *java_globals
+#define JG_DC      , JG_D
+#define JG_C       dir_globals
+#define JG_CC      , JG_C
+int java_globals_id;
+#else
+#define JG(v) (java_globals.v)
+#define JG_FETCH()
+#define JG_D
+#define JG_DC
+#define JG_C
+#define JG_CC
+php_java_globals javadir_globals;
+#endif
+
 static zend_class_entry java_class_entry;
 
 static PHP_INI_MH(OnIniUpdate) {
@@ -106,15 +127,17 @@ PHP_INI_END()
  * Destroy a Java Virtual Machine.
  */
 void jvm_destroy() {
-  if (php_reflect) (*jenv)->DeleteGlobalRef(jenv, php_reflect);
-  if (jvm) {
-    (*jvm)->DetachCurrentThread(jvm);
-    (*jvm)->DestroyJavaVM(jvm);
-    jvm = 0;
+  JG_FETCH();
+
+  if (JG(php_reflect)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), JG(php_reflect));
+  if (JG(jvm)) {
+    (*JG(jvm))->DetachCurrentThread(JG(jvm));
+    (*JG(jvm))->DestroyJavaVM(JG(jvm));
+    JG(jvm) = 0;
   }
   if (dl_handle) DL_UNLOAD(dl_handle);
-  php_reflect = 0;
-  jenv = 0;
+  JG(php_reflect) = 0;
+  JG(jenv) = 0;
 }
 
 /*
@@ -134,9 +157,10 @@ static void addJVMOption(JavaVMInitArgs *vm_args, char *name, char *value) {
 #endif
 
 static int jvm_create() {
+  JG_FETCH();
 
   int rc;
-  jclass local_php_reflect;
+  jobject local_php_reflect;
   jthrowable error;
 
   jint (JNICALL *JNI_CreateVM)(const void*,const void*,void*);
@@ -217,21 +241,22 @@ static int jvm_create() {
 
 #endif
 
-  rc = (*JNI_CreateVM)(&jvm, &jenv, &vm_args);
+  rc = (*JNI_CreateVM)(&JG(jvm), &JG(jenv), &vm_args);
 
   if (rc) {
     php_error(E_ERROR, "Unable to create Java Virtual Machine");
     return rc;
   }
 
-  local_php_reflect = (*jenv)->FindClass(jenv, "net/php/reflect");
-  error = (*jenv)->ExceptionOccurred(jenv);
+  JG(reflect_class) = (*JG(jenv))->FindClass(JG(jenv), "net/php/reflect");
+  error = (*JG(jenv))->ExceptionOccurred(JG(jenv));
   if (error) {
     jclass errClass;
     jmethodID toString;
     jobject errString;
     const char *errAsUTF;
     jboolean isCopy;
+    JNIEnv *jenv = JG(jenv);
     (*jenv)->ExceptionClear(jenv);
     errClass = (*jenv)->GetObjectClass(jenv, error);
     toString = (*jenv)->GetMethodID(jenv, errClass, "toString",
@@ -244,13 +269,17 @@ static int jvm_create() {
     return -1;
   }
 
-  php_reflect = (*jenv)->NewGlobalRef(jenv, local_php_reflect);
+  local_php_reflect = (*JG(jenv))->AllocObject(JG(jenv), JG(reflect_class));
+  JG(php_reflect) = (*JG(jenv))->NewGlobalRef(JG(jenv), local_php_reflect);
   return rc;
 }
 
 /***************************************************************************/
 
 static jobjectArray _java_makeArray(int argc, pval** argv) {
+  JG_FETCH();
+  JNIEnv *jenv = JG(jenv);
+
   jclass objectClass = (*jenv)->FindClass(jenv, "java/lang/Object");
   jobjectArray result = (*jenv)->NewObjectArray(jenv, argc, objectClass, 0);
   jobject arg;
@@ -273,23 +302,23 @@ static jobjectArray _java_makeArray(int argc, pval** argv) {
         break;
 
       case IS_BOOL:
-        makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+        makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",
           "(Z)Ljava/lang/Object;");
-        arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+        arg = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,
           (jboolean)(argv[i]->value.lval));
         break;
 
       case IS_LONG:
-        makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+        makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",
           "(J)Ljava/lang/Object;");
-        arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+        arg = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,
           (jlong)(argv[i]->value.lval));
         break;
 
       case IS_DOUBLE:
-        makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+        makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",
           "(D)Ljava/lang/Object;");
-        arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+        arg = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,
           (jdouble)(argv[i]->value.dval));
         break;
 
@@ -323,6 +352,9 @@ static int checkError(pval *value) {
 void java_call_function_handler
   (INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
 {
+  JG_FETCH();
+  JNIEnv *jenv;
+
   pval *object = property_reference->object;
   zend_overloaded_element *function_name = (zend_overloaded_element *)
     property_reference->elements_list->tail->data;
@@ -333,9 +365,10 @@ void java_call_function_handler
   pval **arguments = (pval **) emalloc(sizeof(pval *)*arg_count);
   getParametersArray(ht, arg_count, arguments);
 
-  if (iniUpdated && jenv) jvm_destroy();
-  if (!jenv) jvm_create();
-  if (!jenv) return;
+  if (iniUpdated && JG(jenv)) jvm_destroy();
+  if (!JG(jenv)) jvm_create();
+  if (!JG(jenv)) return;
+  jenv = JG(jenv);
 
   if (!strcmp("java",function_name->element.value.str.val)) {
 
@@ -343,12 +376,12 @@ void java_call_function_handler
        First argument is the class name.  Any additional arguments will
        be treated as constructor parameters. */
 
-    jmethodID co = (*jenv)->GetStaticMethodID(jenv, php_reflect, "CreateObject",
+    jmethodID co = (*jenv)->GetMethodID(jenv, JG(reflect_class), "CreateObject",
       "(Ljava/lang/String;[Ljava/lang/Object;J)V");
     jstring className=(*jenv)->NewStringUTF(jenv, arguments[0]->value.str.val);
     (pval*)(long)result = object;
 
-    (*jenv)->CallStaticVoidMethod(jenv, php_reflect, co,
+    (*jenv)->CallVoidMethod(jenv, JG(php_reflect), co,
       className, _java_makeArray(arg_count-1, arguments+1), result);
 
     (*jenv)->DeleteLocalRef(jenv, className);
@@ -362,14 +395,14 @@ void java_call_function_handler
 
     /* invoke a method on the given object */
 
-    jmethodID invoke = (*jenv)->GetStaticMethodID(jenv, php_reflect, "Invoke",
+    jmethodID invoke = (*jenv)->GetMethodID(jenv, JG(reflect_class), "Invoke",
       "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V");
     zend_hash_index_find(object->value.obj.properties, 0, (void**) &handle);
     obj = zend_list_find((*handle)->value.lval, &type);
     method = (*jenv)->NewStringUTF(jenv, function_name->element.value.str.val);
     (pval*)(long)result = return_value;
 
-    (*jenv)->CallStaticVoidMethod(jenv, php_reflect, invoke,
+    (*jenv)->CallVoidMethod(jenv, JG(php_reflect), invoke,
       obj, method, _java_makeArray(arg_count, arguments), result);
 
     (*jenv)->DeleteLocalRef(jenv, method);
@@ -386,30 +419,38 @@ void java_call_function_handler
 
 PHP_FUNCTION(java_last_exception_get)
 {
+  JG_FETCH();
+
   jlong result = 0;
   jmethodID lastEx;
 
+  if (ZEND_NUM_ARGS()!=0) WRONG_PARAM_COUNT;
+
   (pval*)(long)result = return_value;
   
-  lastEx = (*jenv)->GetStaticMethodID(jenv, php_reflect, "lastException",
-          "(J)V");
+  lastEx = (*JG(jenv))->GetMethodID(JG(jenv), JG(reflect_class), 
+          "lastException", "(J)V");
 
-  (*jenv)->CallStaticVoidMethod(jenv, php_reflect, lastEx, result);
+  (*JG(jenv))->CallVoidMethod(JG(jenv), JG(php_reflect), lastEx, result);
 }
 
 /***************************************************************************/
 
 PHP_FUNCTION(java_last_exception_clear)
 {
+  JG_FETCH();
+
   jlong result = 0;
   jmethodID clearEx;
 
+  if (ZEND_NUM_ARGS()!=0) WRONG_PARAM_COUNT;
+
   (pval*)(long)result = return_value;
   
-  clearEx = (*jenv)->GetStaticMethodID(jenv, php_reflect, "clearException",
-          "()V");
+  clearEx = (*JG(jenv))->GetMethodID(JG(jenv), JG(reflect_class), 
+          "clearException", "()V");
 
-  (*jenv)->CallStaticVoidMethod(jenv, php_reflect, clearEx);
+  (*JG(jenv))->CallVoidMethod(JG(jenv), JG(php_reflect), clearEx);
 }
 
 /***************************************************************************/
@@ -417,6 +458,9 @@ PHP_FUNCTION(java_last_exception_clear)
 static pval _java_getset_property
   (zend_property_reference *property_reference, jobjectArray value)
 {
+  JG_FETCH();
+  JNIEnv *jenv = JG(jenv);
+
   pval presult;
   jlong result = 0;
   pval **pobject;
@@ -441,10 +485,10 @@ static pval _java_getset_property
       "Attempt to access a Java property on a non-Java object");
   } else {
     /* invoke the method */
-    jmethodID gsp = (*jenv)->GetStaticMethodID(jenv, php_reflect, "GetSetProp",
+    jmethodID gsp = (*jenv)->GetMethodID(jenv, JG(reflect_class), "GetSetProp",
       "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V");
-    (*jenv)->CallStaticVoidMethod
-       (jenv, php_reflect, gsp, obj, propName, value, result);
+    (*jenv)->CallVoidMethod
+       (jenv, JG(php_reflect), gsp, obj, propName, value, result);
   }
 
   (*jenv)->DeleteLocalRef(jenv, propName);
@@ -472,9 +516,16 @@ int java_set_property_handler
 /***************************************************************************/
 
 static void _php_java_destructor(void *jobject) {
-  if (jenv) (*jenv)->DeleteGlobalRef(jenv, jobject);
+  JG_FETCH();
+  if (JG(jenv)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), jobject);
 }
 
+#ifdef ZTS
+static void alloc_java_globals_ctor(php_java_globals *java_globals) {
+  memset(java_globals, 0, sizeof(php_java_globals));
+}
+#endif
+
 PHP_MINIT_FUNCTION(java) {
   INIT_OVERLOADED_CLASS_ENTRY(java_class_entry, "java", NULL,
     java_call_function_handler,
@@ -494,13 +545,19 @@ PHP_MINIT_FUNCTION(java) {
     libpath=PG(extension_dir);
   }
 
+#ifdef ZTS
+  java_globals_id = ts_allocate_id(sizeof(php_java_globals), 
+    (ts_allocate_ctor)alloc_java_globals_ctor, NULL);
+#endif
+
   return SUCCESS;
 }
 
 
 PHP_MSHUTDOWN_FUNCTION(java) {
+  JG_FETCH();
   UNREGISTER_INI_ENTRIES();
-  if (jvm) jvm_destroy();
+  if (JG(jvm)) jvm_destroy();
   return SUCCESS;
 }
 
@@ -620,8 +677,16 @@ JNIEXPORT void JNICALL Java_net_php_reflect_setException
 JNIEXPORT void JNICALL Java_net_php_reflect_setEnv
   (JNIEnv *newJenv, jclass self)
 {
+  JG_FETCH();
+  jobject local_php_reflect;
+
   iniUpdated=0;
-  jenv=newJenv;
-  if (!self) self = (*jenv)->FindClass(jenv, "net/php/reflect");
-  php_reflect = (*jenv)->NewGlobalRef(jenv, self);
+  JG(jenv)=newJenv;
+
+  if (!self) self = (*JG(jenv))->FindClass(JG(jenv), "net/php/reflect");
+  JG(reflect_class) = self;
+
+  if (JG(php_reflect)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), JG(php_reflect));
+  local_php_reflect = (*JG(jenv))->AllocObject(JG(jenv), JG(reflect_class));
+  JG(php_reflect) = (*JG(jenv))->NewGlobalRef(JG(jenv), local_php_reflect);
 }
index 35842ea939e140ba6a867cf6d5530432d1fa1505..3cf53aece288ddfac39cfbc0984255ebe9c824a2 100644 (file)
@@ -88,17 +88,17 @@ public class reflect {
     }
   }
 
-  static Throwable lastException = null;
+  Throwable lastException = null;
 
-  static void lastException(long result) {
+  void lastException(long result) {
     setResult(result, lastException);
   }
 
-  static void clearException() {
+  void clearException() {
     lastException = null;
   }
 
-  static void setException(long result, Throwable e) {
+  void setException(long result, Throwable e) {
     if (e instanceof InvocationTargetException) {
       Throwable t = ((InvocationTargetException)e).getTargetException();
       if (t!=null) e=t;
@@ -111,7 +111,7 @@ public class reflect {
   //
   // Create an new instance of a given class
   //
-  public static void CreateObject(String name, Object args[], long result) {
+  public void CreateObject(String name, Object args[], long result) {
     try {
       Vector matches = new Vector();
 
@@ -233,7 +233,7 @@ public class reflect {
   //
   // Invoke a method on a given object
   //
-  public static void Invoke
+  public void Invoke
     (Object object, String method, Object args[], long result)
   {
 
@@ -281,9 +281,10 @@ public class reflect {
   //
   // Get or Set a property
   //
-  public static void GetSetProp
+  public void GetSetProp
     (Object object, String prop, Object args[], long result)
   {
+System.out.println(object + "." + prop);
     try {
 
       for (Class jclass = object.getClass();;jclass=(Class)object) {
@@ -340,7 +341,7 @@ public class reflect {
   //
   // Helper routines for the C implementation
   //
-  public static Object MakeArg(boolean b) { return new Boolean(b); }
-  public static Object MakeArg(long l)    { return new Long(l); }
-  public static Object MakeArg(double d)  { return new Double(d); }
+  public Object MakeArg(boolean b) { return new Boolean(b); }
+  public Object MakeArg(long l)    { return new Long(l); }
+  public Object MakeArg(double d)  { return new Double(d); }
 }
index 6c64dcfe400ec069ff6de8e01f6dd04d21a74a21..097bfabf1a304573e548c5e53e469135951e6a51 100644 (file)
@@ -22,14 +22,12 @@ What is PHP4 ext/java?
 
      4) Exceptions raised result in PHP warnings, and null results.  The
         warnings may be eliminated by prefixing the method call with an
-        "@" sign.  The following experimental APIs may be used to retrieve
-        and reset the last error:
+        "@" sign.  The following APIs may be used to retrieve and reset
+        the last error:
 
           java_last_exception_get()
           java_last_exception_clear()
 
-        These APIs are not currently implemented in a reentrant fashion.
-
      5) Overload resolution is in general a hard problem given the
         differences in types between the two languages.  The PHP Java
        extension employs a simple, but fairly effective, metric for
index 9d0cf7516e27c215b5415e4fffa630c98e819cfe..83db3d4b7aa7ed99213f29cdd7de70021fb47313 100644 (file)
@@ -68,12 +68,33 @@ static char *javahome  = 0;
 static char *javalib   = 0;
 
 static int iniUpdated  = 0;
-
-static JavaVM *jvm = 0;
-static JNIEnv *jenv = 0;
-static jclass php_reflect;
 static void *dl_handle = 0;
 
+typedef struct {
+  JavaVM *jvm;
+  JNIEnv *jenv;
+  jobject php_reflect;
+  jclass  reflect_class;
+} php_java_globals;
+
+#ifdef ZTS
+#define JG(v) (java_globals->v)
+#define JG_FETCH() php_java_globals *java_globals = ts_resource(java_globals_id)
+#define JG_D       php_java_globals *java_globals
+#define JG_DC      , JG_D
+#define JG_C       dir_globals
+#define JG_CC      , JG_C
+int java_globals_id;
+#else
+#define JG(v) (java_globals.v)
+#define JG_FETCH()
+#define JG_D
+#define JG_DC
+#define JG_C
+#define JG_CC
+php_java_globals javadir_globals;
+#endif
+
 static zend_class_entry java_class_entry;
 
 static PHP_INI_MH(OnIniUpdate) {
@@ -106,15 +127,17 @@ PHP_INI_END()
  * Destroy a Java Virtual Machine.
  */
 void jvm_destroy() {
-  if (php_reflect) (*jenv)->DeleteGlobalRef(jenv, php_reflect);
-  if (jvm) {
-    (*jvm)->DetachCurrentThread(jvm);
-    (*jvm)->DestroyJavaVM(jvm);
-    jvm = 0;
+  JG_FETCH();
+
+  if (JG(php_reflect)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), JG(php_reflect));
+  if (JG(jvm)) {
+    (*JG(jvm))->DetachCurrentThread(JG(jvm));
+    (*JG(jvm))->DestroyJavaVM(JG(jvm));
+    JG(jvm) = 0;
   }
   if (dl_handle) DL_UNLOAD(dl_handle);
-  php_reflect = 0;
-  jenv = 0;
+  JG(php_reflect) = 0;
+  JG(jenv) = 0;
 }
 
 /*
@@ -134,9 +157,10 @@ static void addJVMOption(JavaVMInitArgs *vm_args, char *name, char *value) {
 #endif
 
 static int jvm_create() {
+  JG_FETCH();
 
   int rc;
-  jclass local_php_reflect;
+  jobject local_php_reflect;
   jthrowable error;
 
   jint (JNICALL *JNI_CreateVM)(const void*,const void*,void*);
@@ -217,21 +241,22 @@ static int jvm_create() {
 
 #endif
 
-  rc = (*JNI_CreateVM)(&jvm, &jenv, &vm_args);
+  rc = (*JNI_CreateVM)(&JG(jvm), &JG(jenv), &vm_args);
 
   if (rc) {
     php_error(E_ERROR, "Unable to create Java Virtual Machine");
     return rc;
   }
 
-  local_php_reflect = (*jenv)->FindClass(jenv, "net/php/reflect");
-  error = (*jenv)->ExceptionOccurred(jenv);
+  JG(reflect_class) = (*JG(jenv))->FindClass(JG(jenv), "net/php/reflect");
+  error = (*JG(jenv))->ExceptionOccurred(JG(jenv));
   if (error) {
     jclass errClass;
     jmethodID toString;
     jobject errString;
     const char *errAsUTF;
     jboolean isCopy;
+    JNIEnv *jenv = JG(jenv);
     (*jenv)->ExceptionClear(jenv);
     errClass = (*jenv)->GetObjectClass(jenv, error);
     toString = (*jenv)->GetMethodID(jenv, errClass, "toString",
@@ -244,13 +269,17 @@ static int jvm_create() {
     return -1;
   }
 
-  php_reflect = (*jenv)->NewGlobalRef(jenv, local_php_reflect);
+  local_php_reflect = (*JG(jenv))->AllocObject(JG(jenv), JG(reflect_class));
+  JG(php_reflect) = (*JG(jenv))->NewGlobalRef(JG(jenv), local_php_reflect);
   return rc;
 }
 
 /***************************************************************************/
 
 static jobjectArray _java_makeArray(int argc, pval** argv) {
+  JG_FETCH();
+  JNIEnv *jenv = JG(jenv);
+
   jclass objectClass = (*jenv)->FindClass(jenv, "java/lang/Object");
   jobjectArray result = (*jenv)->NewObjectArray(jenv, argc, objectClass, 0);
   jobject arg;
@@ -273,23 +302,23 @@ static jobjectArray _java_makeArray(int argc, pval** argv) {
         break;
 
       case IS_BOOL:
-        makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+        makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",
           "(Z)Ljava/lang/Object;");
-        arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+        arg = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,
           (jboolean)(argv[i]->value.lval));
         break;
 
       case IS_LONG:
-        makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+        makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",
           "(J)Ljava/lang/Object;");
-        arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+        arg = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,
           (jlong)(argv[i]->value.lval));
         break;
 
       case IS_DOUBLE:
-        makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg",
+        makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",
           "(D)Ljava/lang/Object;");
-        arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg,
+        arg = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,
           (jdouble)(argv[i]->value.dval));
         break;
 
@@ -323,6 +352,9 @@ static int checkError(pval *value) {
 void java_call_function_handler
   (INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
 {
+  JG_FETCH();
+  JNIEnv *jenv;
+
   pval *object = property_reference->object;
   zend_overloaded_element *function_name = (zend_overloaded_element *)
     property_reference->elements_list->tail->data;
@@ -333,9 +365,10 @@ void java_call_function_handler
   pval **arguments = (pval **) emalloc(sizeof(pval *)*arg_count);
   getParametersArray(ht, arg_count, arguments);
 
-  if (iniUpdated && jenv) jvm_destroy();
-  if (!jenv) jvm_create();
-  if (!jenv) return;
+  if (iniUpdated && JG(jenv)) jvm_destroy();
+  if (!JG(jenv)) jvm_create();
+  if (!JG(jenv)) return;
+  jenv = JG(jenv);
 
   if (!strcmp("java",function_name->element.value.str.val)) {
 
@@ -343,12 +376,12 @@ void java_call_function_handler
        First argument is the class name.  Any additional arguments will
        be treated as constructor parameters. */
 
-    jmethodID co = (*jenv)->GetStaticMethodID(jenv, php_reflect, "CreateObject",
+    jmethodID co = (*jenv)->GetMethodID(jenv, JG(reflect_class), "CreateObject",
       "(Ljava/lang/String;[Ljava/lang/Object;J)V");
     jstring className=(*jenv)->NewStringUTF(jenv, arguments[0]->value.str.val);
     (pval*)(long)result = object;
 
-    (*jenv)->CallStaticVoidMethod(jenv, php_reflect, co,
+    (*jenv)->CallVoidMethod(jenv, JG(php_reflect), co,
       className, _java_makeArray(arg_count-1, arguments+1), result);
 
     (*jenv)->DeleteLocalRef(jenv, className);
@@ -362,14 +395,14 @@ void java_call_function_handler
 
     /* invoke a method on the given object */
 
-    jmethodID invoke = (*jenv)->GetStaticMethodID(jenv, php_reflect, "Invoke",
+    jmethodID invoke = (*jenv)->GetMethodID(jenv, JG(reflect_class), "Invoke",
       "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V");
     zend_hash_index_find(object->value.obj.properties, 0, (void**) &handle);
     obj = zend_list_find((*handle)->value.lval, &type);
     method = (*jenv)->NewStringUTF(jenv, function_name->element.value.str.val);
     (pval*)(long)result = return_value;
 
-    (*jenv)->CallStaticVoidMethod(jenv, php_reflect, invoke,
+    (*jenv)->CallVoidMethod(jenv, JG(php_reflect), invoke,
       obj, method, _java_makeArray(arg_count, arguments), result);
 
     (*jenv)->DeleteLocalRef(jenv, method);
@@ -386,30 +419,38 @@ void java_call_function_handler
 
 PHP_FUNCTION(java_last_exception_get)
 {
+  JG_FETCH();
+
   jlong result = 0;
   jmethodID lastEx;
 
+  if (ZEND_NUM_ARGS()!=0) WRONG_PARAM_COUNT;
+
   (pval*)(long)result = return_value;
   
-  lastEx = (*jenv)->GetStaticMethodID(jenv, php_reflect, "lastException",
-          "(J)V");
+  lastEx = (*JG(jenv))->GetMethodID(JG(jenv), JG(reflect_class), 
+          "lastException", "(J)V");
 
-  (*jenv)->CallStaticVoidMethod(jenv, php_reflect, lastEx, result);
+  (*JG(jenv))->CallVoidMethod(JG(jenv), JG(php_reflect), lastEx, result);
 }
 
 /***************************************************************************/
 
 PHP_FUNCTION(java_last_exception_clear)
 {
+  JG_FETCH();
+
   jlong result = 0;
   jmethodID clearEx;
 
+  if (ZEND_NUM_ARGS()!=0) WRONG_PARAM_COUNT;
+
   (pval*)(long)result = return_value;
   
-  clearEx = (*jenv)->GetStaticMethodID(jenv, php_reflect, "clearException",
-          "()V");
+  clearEx = (*JG(jenv))->GetMethodID(JG(jenv), JG(reflect_class), 
+          "clearException", "()V");
 
-  (*jenv)->CallStaticVoidMethod(jenv, php_reflect, clearEx);
+  (*JG(jenv))->CallVoidMethod(JG(jenv), JG(php_reflect), clearEx);
 }
 
 /***************************************************************************/
@@ -417,6 +458,9 @@ PHP_FUNCTION(java_last_exception_clear)
 static pval _java_getset_property
   (zend_property_reference *property_reference, jobjectArray value)
 {
+  JG_FETCH();
+  JNIEnv *jenv = JG(jenv);
+
   pval presult;
   jlong result = 0;
   pval **pobject;
@@ -441,10 +485,10 @@ static pval _java_getset_property
       "Attempt to access a Java property on a non-Java object");
   } else {
     /* invoke the method */
-    jmethodID gsp = (*jenv)->GetStaticMethodID(jenv, php_reflect, "GetSetProp",
+    jmethodID gsp = (*jenv)->GetMethodID(jenv, JG(reflect_class), "GetSetProp",
       "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V");
-    (*jenv)->CallStaticVoidMethod
-       (jenv, php_reflect, gsp, obj, propName, value, result);
+    (*jenv)->CallVoidMethod
+       (jenv, JG(php_reflect), gsp, obj, propName, value, result);
   }
 
   (*jenv)->DeleteLocalRef(jenv, propName);
@@ -472,9 +516,16 @@ int java_set_property_handler
 /***************************************************************************/
 
 static void _php_java_destructor(void *jobject) {
-  if (jenv) (*jenv)->DeleteGlobalRef(jenv, jobject);
+  JG_FETCH();
+  if (JG(jenv)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), jobject);
 }
 
+#ifdef ZTS
+static void alloc_java_globals_ctor(php_java_globals *java_globals) {
+  memset(java_globals, 0, sizeof(php_java_globals));
+}
+#endif
+
 PHP_MINIT_FUNCTION(java) {
   INIT_OVERLOADED_CLASS_ENTRY(java_class_entry, "java", NULL,
     java_call_function_handler,
@@ -494,13 +545,19 @@ PHP_MINIT_FUNCTION(java) {
     libpath=PG(extension_dir);
   }
 
+#ifdef ZTS
+  java_globals_id = ts_allocate_id(sizeof(php_java_globals), 
+    (ts_allocate_ctor)alloc_java_globals_ctor, NULL);
+#endif
+
   return SUCCESS;
 }
 
 
 PHP_MSHUTDOWN_FUNCTION(java) {
+  JG_FETCH();
   UNREGISTER_INI_ENTRIES();
-  if (jvm) jvm_destroy();
+  if (JG(jvm)) jvm_destroy();
   return SUCCESS;
 }
 
@@ -620,8 +677,16 @@ JNIEXPORT void JNICALL Java_net_php_reflect_setException
 JNIEXPORT void JNICALL Java_net_php_reflect_setEnv
   (JNIEnv *newJenv, jclass self)
 {
+  JG_FETCH();
+  jobject local_php_reflect;
+
   iniUpdated=0;
-  jenv=newJenv;
-  if (!self) self = (*jenv)->FindClass(jenv, "net/php/reflect");
-  php_reflect = (*jenv)->NewGlobalRef(jenv, self);
+  JG(jenv)=newJenv;
+
+  if (!self) self = (*JG(jenv))->FindClass(JG(jenv), "net/php/reflect");
+  JG(reflect_class) = self;
+
+  if (JG(php_reflect)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), JG(php_reflect));
+  local_php_reflect = (*JG(jenv))->AllocObject(JG(jenv), JG(reflect_class));
+  JG(php_reflect) = (*JG(jenv))->NewGlobalRef(JG(jenv), local_php_reflect);
 }
index 35842ea939e140ba6a867cf6d5530432d1fa1505..3cf53aece288ddfac39cfbc0984255ebe9c824a2 100644 (file)
@@ -88,17 +88,17 @@ public class reflect {
     }
   }
 
-  static Throwable lastException = null;
+  Throwable lastException = null;
 
-  static void lastException(long result) {
+  void lastException(long result) {
     setResult(result, lastException);
   }
 
-  static void clearException() {
+  void clearException() {
     lastException = null;
   }
 
-  static void setException(long result, Throwable e) {
+  void setException(long result, Throwable e) {
     if (e instanceof InvocationTargetException) {
       Throwable t = ((InvocationTargetException)e).getTargetException();
       if (t!=null) e=t;
@@ -111,7 +111,7 @@ public class reflect {
   //
   // Create an new instance of a given class
   //
-  public static void CreateObject(String name, Object args[], long result) {
+  public void CreateObject(String name, Object args[], long result) {
     try {
       Vector matches = new Vector();
 
@@ -233,7 +233,7 @@ public class reflect {
   //
   // Invoke a method on a given object
   //
-  public static void Invoke
+  public void Invoke
     (Object object, String method, Object args[], long result)
   {
 
@@ -281,9 +281,10 @@ public class reflect {
   //
   // Get or Set a property
   //
-  public static void GetSetProp
+  public void GetSetProp
     (Object object, String prop, Object args[], long result)
   {
+System.out.println(object + "." + prop);
     try {
 
       for (Class jclass = object.getClass();;jclass=(Class)object) {
@@ -340,7 +341,7 @@ public class reflect {
   //
   // Helper routines for the C implementation
   //
-  public static Object MakeArg(boolean b) { return new Boolean(b); }
-  public static Object MakeArg(long l)    { return new Long(l); }
-  public static Object MakeArg(double d)  { return new Double(d); }
+  public Object MakeArg(boolean b) { return new Boolean(b); }
+  public Object MakeArg(long l)    { return new Long(l); }
+  public Object MakeArg(double d)  { return new Double(d); }
 }