# HG changeset patch # User William Welliver # Date 1638467838 18000 # Thu Dec 02 12:57:18 2021 -0500 # Node ID a400c396aec7b179e705c8f400f1149a5ad20c30 # Parent 96df23e14c51337457de821ab36ff47d142f4e66 disable mach_override and grab the interpreter lock when performing respondsToSelector on a pike object diff --git a/ObjC.mmod b/ObjC.mmod --- a/ObjC.mmod +++ b/ObjC.mmod @@ -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 @@ pop_n_elems(args); } - +#if 0 // set up method override for void override_objc_getClass() { @@ -549,6 +548,7 @@ 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) diff --git a/PiObjCObject.m b/PiObjCObject.m --- a/PiObjCObject.m +++ b/PiObjCObject.m @@ -1017,7 +1017,9 @@ 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 @@ } */ + + - 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