disable mach_override and grab the interpreter lock when performing respondsToSelector on a pike object
2 files changed, 71 insertions(+), 10 deletions(-)

M ObjC.mmod
M PiObjCObject.m
M ObjC.mmod +5 -5
@@ 1,7 1,6 @@ 
 
 #define THIS_IS_OBJC_OBJECT_HOLDER 1
 
-#include "mach_override.h"
 #include "ffi/ffi.h"
 #include "piobjc.h"
 #import "util.h"

          
@@ 20,9 19,9 @@ 
 /*! @decl int index(int pid, int use_main_thread, string bundlePath, string systemPath, string carbonPath)
  *!
  */
-void override_object_setInstanceVariable();
-void override_object_getInstanceVariable();
-void override_objc_getClass();
+//void override_object_setInstanceVariable();
+//void override_object_getInstanceVariable();
+//void override_objc_getClass();
 
 void pike_init_piobjc_foundation();
 void pike_init_piobjc_appkit();

          
@@ 470,7 469,7 @@ PIKEFUN void new_class(string name, prog
    pop_n_elems(args);
 }
 
-
+#if 0
 // set up method override for 
 void override_objc_getClass()
 {

          
@@ 549,6 548,7 @@ void override_object_getInstanceVariable
       Pike_error("an error occurred while setting up the Objective-C environment.\n");
   }
 }
+#endif /* 0 */
 int iq =0;
 
 Ivar oc_object_getInstanceVariable(id obj, char * vn, void ** var)

          
M PiObjCObject.m +66 -5
@@ 1017,7 1017,9 @@ void dispatch_pike_class_method(struct p
   struct svalue * func;
   struct Method** lst;
   void* cookie;
-
+  bool res = NO;
+  struct thread_state *state;
+  
   LOG("PiObjCObject(%s).respondsToSelector: %s? ", object_getClassName(self), sel_getName(aSelector));
   NSLog([self description]);
 	/*

          
@@ 1042,12 1044,71 @@ void dispatch_pike_class_method(struct p
   }
 
 */
+   
+   
 
-  func = get_func_by_selector(pobject, aSelector);
+   if((state = thread_state_for_id(th_self()))!=NULL)
+   {
+     /* This is a pike thread.  Do we have the interpreter lock? */
+     if(!state->swapped)
+     {
+       /* Yes.  Go for it... */
+	     func = get_func_by_selector(pobject, aSelector);
+
+	     if(func) { LOG("YES (1)%s\n", ""); free_svalue(func); free(func); res = YES;}
+	     else if(has_objc_method(self, aSelector)) { LOG("YES (2)%s\n", ""); res = YES;}
+	     else { LOG("NO%s\n", "");  res = NO; }	 
+     }
+     else
+     {
+       /* Nope, let's get it... */
+       mt_lock_interpreter();
+       SWAP_IN_THREAD(state);
+
+       func = get_func_by_selector(pobject, aSelector);
 
-  if(func) { LOG("YES (1)%s\n", ""); free_svalue(func); free(func); return YES;}
-  else if(has_objc_method(self, aSelector)) { LOG("YES (2)%s\n", ""); return YES;}
-  else { LOG("NO%s\n", "");  return NO; }
+       if(func) { LOG("YES (1)%s\n", ""); free_svalue(func); free(func); res = YES;}
+       else if(has_objc_method(self, aSelector)) { LOG("YES (2)%s\n", ""); res = YES;}
+       else { LOG("NO%s\n", "");  res = NO; }
+      
+       /* Restore */
+       SWAP_OUT_THREAD(state);
+       mt_unlock_interpreter();
+      }
+    }
+    else
+    {
+       /* Not a pike thread.  Create a temporary thread_id... */
+       struct object *thread_obj;
+       mt_lock_interpreter();
+       init_interpreter();
+       Pike_interpreter.stack_top=((char *)&state)+ (thread_stack_size-16384) * STACK_DIRECTION;
+       Pike_interpreter.recoveries = NULL;
+       thread_obj = fast_clone_object(thread_id_prog);
+       INIT_THREAD_STATE((struct thread_state *)(thread_obj->storage +
+                                                   thread_storage_offset));
+       num_threads++;
+       thread_table_insert(Pike_interpreter.thread_state);
+
+     func = get_func_by_selector(pobject, aSelector);
+
+       if(func) { LOG("YES (1)%s\n", ""); free_svalue(func); free(func); res = YES;}
+       else if(has_objc_method(self, aSelector)) { LOG("YES (2)%s\n", ""); res = YES;}
+       else { LOG("NO%s\n", "");  res = NO; }
+	 
+       cleanup_interpret();      /* Must be done before EXIT_THREAD_STATE */
+       Pike_interpreter.thread_state->status=THREAD_EXITED;
+       co_signal(&Pike_interpreter.thread_state->status_change);
+       thread_table_delete(Pike_interpreter.thread_state);
+       EXIT_THREAD_STATE(Pike_interpreter.thread_state);
+       Pike_interpreter.thread_state=NULL;
+       free_object(thread_obj);
+       thread_obj = NULL;
+       num_threads--;
+       mt_unlock_interpreter();     
+    }
+   
+	return res;
 }
 
 + (BOOL) respondsToSelector:(SEL) aSelector