7 files changed, 97 insertions(+), 59 deletions(-)

M AppKit.mmod
M Makefile.in
M PiObjCObject.m
M dynamic_class.m
M method_dispatch.m
M mkapp.pike
M util.h
M AppKit.mmod +1 -0
@@ 68,6 68,7 @@ 
  #import <AppKit/NSApplication.h>
  #import <Foundation/NSBundle.h>
  #import <Foundation/NSString.h>
+ #import <AppKit/NSPanel.h>
 
  #define _GNU_SOURCE
  #define THIS_IS_APPKIT 1

          
M Makefile.in +3 -3
@@ 1,17 1,17 @@ 
 # $Id: Makefile.in,v 1.39 2008-01-04 01:39:30 hww3 Exp $
 @make_variables@
 VPATH=@srcdir@:@srcdir@/../..:../..
-UDISOBJS=libudis86/decode.o libudis86/input.o libudis86/itab.o libudis86/syn-att.o libudis86/syn-intel.o libudis86/syn.o libudis86/udis86.o
+#UDISOBJS=libudis86/decode.o libudis86/input.o libudis86/itab.o libudis86/syn-att.o libudis86/syn-intel.o libudis86/syn.o libudis86/udis86.o
 #FFIOBJS=libffi/src/types.o libffi/src/prep_cif.o libffi/src/@OC_ARCH@/ffi_darwin.o libffi/src/@OC_ARCH@/darwin.o
 #FFIOBJS=libffi/src/types.o libffi/src/prep_cif.o libffi/src/@OC_ARCH@/ffi_darwin.o libffi/src/@OC_ARCH@/darwin_closure.o libffi/src/@OC_ARCH@/darwin.o
-OBJS=$(UDISOBJS) ObjC.o dynamic_class.o util.o proxy-registry.o OC_Array.o OC_Mapping.o Foundation.o AppKit.o PiObjCObject.o   mach_override.o method_dispatch.o  _mixins.o 
+OBJS=$(UDISOBJS) ObjC.o dynamic_class.o util.o proxy-registry.o OC_Array.o OC_Mapping.o Foundation.o AppKit.o PiObjCObject.o  method_dispatch.o  _mixins.o 
 MODDIR=Public.pmod/
 MODNAME=ObjectiveC
 MODULE_CLEAN_EXTRA=$(UDISOBJS)
 AUTODOC_SRC_IN=objectivec.cmod
 MODULE_LDFLAGS=@LDFLAGS@ @LIBS@ -framework AddressBook -framework AppKit -framework Quartz -lffi
 #MODULE_CPPFLAGS=-Ilibffi -Ilibffi/include
-MODULE_CFLAGS=@module_cflags@ -fobjc-exceptions -FQuartz
+MODULE_CFLAGS=@module_cflags@ -DFFI_LEGACY_CLOSURE_API -fobjc-exceptions -FQuartz
 MODULE_INSTALL=install_frameworks
 
 

          
M PiObjCObject.m +1 -0
@@ 75,6 75,7 @@ 
 #import  <Foundation/NSInvocation.h>
 #import  <Foundation/NSString.h>
 #import "PiObjCObject.h"
+#include "proxy-registry.h"
 
 extern int async_error_mode;
 void dispatch_pike_method(struct object * pobject, SEL sel, NSInvocation * anInvocation);

          
M dynamic_class.m +9 -0
@@ 5,6 5,7 @@ 
 #import "OC_Mapping.h"
 #include "piobjc.h"
 #include "method_dispatch.h"
+#include "proxy-registry.h"
 
 #undef THIS
 #define THIS OBJ2_DYNAMIC_OBJECT(Pike_fp->current_object)

          
@@ 494,7 495,11 @@ LOG("encoding mapping as OC_Mapping%s\n"
        case 'd':
        case 'f':
 	msgResult = malloc(sizeof(double));
+#if defined(__aarch64__)
+        ffi_call(cif,  FFI_FN(objc_msgSend), msgResult, argumentList);
+#else
         ffi_call(cif,  FFI_FN(objc_msgSend_fpret), msgResult, argumentList);
+#endif
         break;  
 
        

          
@@ 503,7 508,11 @@ LOG("encoding mapping as OC_Mapping%s\n"
        case '(':
         THREADS_ALLOW();
         Pike_error("No, no, no... we've not implemented struct returns yet.\n");
+#if defined(__aarch64__)
+        ffi_call(cif, FFI_FN(objc_msgSend), msgResult, argumentList);
+#else
         ffi_call(cif, FFI_FN(objc_msgSend_stret), msgResult, argumentList);
+#endif
      	  THREADS_DISALLOW();
         break;
 

          
M method_dispatch.m +71 -51
@@ 11,11 11,13 @@ 
  *   flt_args	bitfield: There are float arguments at these positions.
  *   dbl_args	bitfield: There are double arguments at these positions.
  */
+
 #import <Foundation/NSHost.h>
 #import <CoreFoundation/CoreFoundation.h>
 #import  <Foundation/NSString.h>
 #include <sys/mman.h>
 #include "piobjc.h"
+#include <ffi/ffi.h>
 
 extern void low_create_pike_object(ffi_cif* cif, void* resp, void** args, void* userdata);
 extern void low_f_objc_dynamic_instance_method(ffi_cif* cif, void* resp, void** args, void* userdata);

          
@@ 327,7 329,7 @@ static const char ulong_type[] = { _C_UL
   /* Build FFI argumentlist description */
 	LOG("cif will have num args: %d\n", numargs);
 	
-    cl_arg_types = malloc(sizeof(ffi_type*) * (numargs));
+    cl_arg_types = calloc(sizeof(ffi_type*) * (numargs), 1);
     if (cl_arg_types == NULL) {
       free(cl_ret_type);
       Pike_error("make_ffi_for_method: Unable to allocate memory.\n");

          
@@ 345,7 347,7 @@ printf("arg type %d is null\n", i);
     }
 
     /* Create the invocation description */
-    cif = malloc(sizeof(*cif));
+    cif = calloc(sizeof(*cif), 1);
     if (cif == NULL) {
       free(cl_arg_types);
       Pike_error("make_ffi_for_method: Unable to allocate memory.\n");

          
@@ 367,6 369,7 @@ printf("arg type %d is null\n", i);
 void * make_create_stub(struct program * prog)
 {
   static ffi_cif* init_cif = NULL;
+  void * codeloc;
   ffi_closure * closure = NULL;
   ffi_status rv;
   ffi_type** cl_arg_types;

          
@@ 381,7 384,7 @@ void * make_create_stub(struct program *
 
   if(init_cif == NULL)
   {
-    cl_arg_types = malloc(sizeof(ffi_type *) * 2);
+    cl_arg_types = calloc(sizeof(ffi_type *) * 2, 1);
     if(cl_arg_types == NULL)
     {
       Pike_error("make_init_stub: out of memory\n");

          
@@ 390,7 393,7 @@ void * make_create_stub(struct program *
     cl_arg_types[0] = &ffi_type_pointer;
     cl_arg_types[1] = &ffi_type_pointer;
 
-    init_cif = malloc(sizeof(ffi_cif));
+    init_cif = calloc(1, sizeof(ffi_cif));
 
     rv = ffi_prep_cif(init_cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer, cl_arg_types);
     if(rv != FFI_OK)

          
@@ 400,15 403,14 @@ void * make_create_stub(struct program *
     }
   }
 
-  closure = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
-             MAP_ANON | MAP_PRIVATE, -1, 0);  
+  closure = ffi_closure_alloc(sizeof(ffi_closure), &codeloc);
   
-  if(closure == ((void*)-1))
+  if(!closure)
   {
     Pike_error("quick_make_stub: out of memory\n");
   }  
 
-  rv = ffi_prep_closure(closure, init_cif, disp, prog);
+  rv = ffi_prep_closure_loc(closure, init_cif, disp, prog, codeloc);
 
   if(rv != FFI_OK)
   {

          
@@ 416,11 418,13 @@ void * make_create_stub(struct program *
     Pike_error("Cannot create FFI closure.\n");
   }
 
+#if 0
   // Ensure that the closure will execute on all architectures.
   if (mprotect(closure, sizeof(closure), PROT_READ | PROT_EXEC) == -1)
   {
     Pike_error("quick_make_stub: unable to make executable\n");
   }
+#endif /* 0 */
 
   return (void *)closure;
 }

          
@@ 428,6 432,7 @@ void * make_create_stub(struct program *
 void * make_class_stub(struct program * prog)
 {
   static ffi_cif* init_cif = NULL;
+  void * codeloc;
   ffi_closure * closure = NULL;
   ffi_status rv;
   ffi_type** cl_arg_types;

          
@@ 441,7 446,7 @@ void * make_class_stub(struct program * 
 
   if(init_cif == NULL)
   {
-    cl_arg_types = malloc(sizeof(ffi_type *) * 2);
+    cl_arg_types = calloc(sizeof(ffi_type *) * 2, 1);
     if(cl_arg_types == NULL)
     {
       Pike_error("make_init_stub: out of memory\n");

          
@@ 450,7 455,7 @@ void * make_class_stub(struct program * 
     cl_arg_types[0] = &ffi_type_pointer;
     cl_arg_types[1] = &ffi_type_pointer;
 
-    init_cif = malloc(sizeof(ffi_cif));
+    init_cif = calloc(sizeof(ffi_cif), 1);
 
     rv = ffi_prep_cif(init_cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer, cl_arg_types);
     if(rv != FFI_OK)

          
@@ 460,15 465,14 @@ void * make_class_stub(struct program * 
     }
   }
 
-  closure = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
-             MAP_ANON | MAP_PRIVATE, -1, 0);  
+  closure = ffi_closure_alloc(sizeof(ffi_closure), &codeloc);
   
-  if(closure == ((void*)-1))
+  if(!closure)
   {
     Pike_error("quick_make_stub: out of memory\n");
   }  
 
-  rv = ffi_prep_closure(closure, init_cif, disp, prog);
+  rv = ffi_prep_closure_loc(closure, init_cif, disp, prog, codeloc);
 
   if(rv != FFI_OK)
   {

          
@@ 476,11 480,13 @@ void * make_class_stub(struct program * 
     Pike_error("Cannot create FFI closure.\n");
   }
 
+#if 0
   // Ensure that the closure will execute on all architectures.
   if (mprotect(closure, sizeof(closure), PROT_READ | PROT_EXEC) == -1)
   {
     Pike_error("quick_make_stub: unable to make executable\n");
   }
+#endif /* 0 */
 
   return (void *)closure;
 }

          
@@ 490,6 496,7 @@ void * make_class_func_stub(struct progr
 {
   int z;
   static ffi_cif* init_cif = NULL;
+  void * codeloc;
   ffi_closure * closure = NULL;
   ffi_status rv;
   ffi_type** cl_arg_types;

          
@@ 521,7 528,7 @@ void * make_class_func_stub(struct progr
     int numargs;
     methodSig = [NSMethodSignature signatureWithObjCTypes: methodTypes];
     numargs = [methodSig numberOfArguments];
-    cl_arg_types = malloc(sizeof(ffi_type *) * numargs);
+    cl_arg_types = calloc(sizeof(ffi_type *) * numargs, 1);
     if(cl_arg_types == NULL)
     {
       Pike_error("make_init_stub: out of memory\n");

          
@@ 586,7 593,7 @@ void * make_class_func_stub(struct progr
       }
     }
 
-    init_cif = malloc(sizeof(ffi_cif));
+    init_cif = calloc(sizeof(ffi_cif), 1);
 
     rv = ffi_prep_cif(init_cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer, cl_arg_types);
     if(rv != FFI_OK)

          
@@ 596,15 603,14 @@ void * make_class_func_stub(struct progr
     }
   }
 
-  closure = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
-             MAP_ANON | MAP_PRIVATE, -1, 0);  
+  closure = ffi_closure_alloc(sizeof(ffi_closure), &codeloc);
   
-  if(closure == ((void*)-1))
+  if(!closure)
   {
     Pike_error("quick_make_stub: out of memory\n");
   }  
 
-  rv = ffi_prep_closure(closure, init_cif, disp, dta);
+  rv = ffi_prep_closure_loc(closure, init_cif, disp, dta, codeloc);
 
   if(rv != FFI_OK)
   {

          
@@ 612,11 618,13 @@ void * make_class_func_stub(struct progr
     Pike_error("Cannot create FFI closure.\n");
   }
 
+#if 0
   // Ensure that the closure will execute on all architectures.
   if (mprotect(closure, sizeof(closure), PROT_READ | PROT_EXEC) == -1)
   {
     Pike_error("quick_make_stub: unable to make executable\n");
   }
+#endif /* 0 */
 
   return (void *)closure;
 }

          
@@ 625,6 633,7 @@ void * make_class_func_stub(struct progr
 void * make_dynamic_method_stub(char * function_name)
 {
   static ffi_cif* init_cif = NULL;
+  void * codeloc;
   ffi_closure * closure = NULL;
   ffi_status rv;
   ffi_type** cl_arg_types;

          
@@ 639,7 648,7 @@ void * make_dynamic_method_stub(char * f
 
   if(init_cif == NULL)
   {
-    cl_arg_types = malloc(sizeof(ffi_type *));
+    cl_arg_types = calloc(sizeof(ffi_type *), 1);
     if(cl_arg_types == NULL)
     {
       Pike_error("make_init_stub: out of memory\n");

          
@@ 647,7 656,7 @@ void * make_dynamic_method_stub(char * f
     
     cl_arg_types[0] = &ffi_type_pointer;
 
-    init_cif = malloc(sizeof(ffi_cif));
+    init_cif = calloc(sizeof(ffi_cif), 1);
 
     rv = ffi_prep_cif(init_cif, FFI_DEFAULT_ABI, 1, &ffi_type_pointer, cl_arg_types);
     if(rv != FFI_OK)

          
@@ 657,15 666,14 @@ void * make_dynamic_method_stub(char * f
     }
   }
 
-  closure = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
-             MAP_ANON | MAP_PRIVATE, -1, 0);  
+  closure = ffi_closure_alloc(sizeof(ffi_closure), &codeloc);
   
-  if(closure == ((void*)-1))
+  if(!closure)
   {
     Pike_error("quick_make_stub: out of memory\n");
   }
   
-  rv = ffi_prep_closure(closure, init_cif, disp, strdup(function_name));
+  rv = ffi_prep_closure_loc(closure, init_cif, disp, strdup(function_name), codeloc);
 
   if(rv != FFI_OK)
   {

          
@@ 673,11 681,13 @@ void * make_dynamic_method_stub(char * f
     Pike_error("Cannot create FFI closure.\n");
   }
 
+#if 0
   // Ensure that the closure will execute on all architectures.
   if (mprotect(closure, sizeof(closure), PROT_READ | PROT_EXEC) == -1)
   {
     Pike_error("quick_make_stub: unable to make executable\n");
   }
+#endif /* 0 */
 
   return (void *)closure;
 }

          
@@ 687,6 697,7 @@ void * make_dynamic_method_stub(char * f
 void * quick_make_stub(void * dta, void * func)
 {
   static ffi_cif* init_cif = NULL;
+  void * codeloc;
   ffi_closure * closure = NULL;
   ffi_status rv;
   ffi_type** cl_arg_types;

          
@@ 695,7 706,7 @@ void * quick_make_stub(void * dta, void 
   
   if(init_cif == NULL)
   {
-    cl_arg_types = malloc(sizeof(ffi_type *) * 2);
+    cl_arg_types = calloc(sizeof(ffi_type *) * 2, 1);
     if(cl_arg_types == NULL)
     {
       Pike_error("quick_make_stub: out of memory\n");

          
@@ 704,7 715,7 @@ void * quick_make_stub(void * dta, void 
     cl_arg_types[0] = &ffi_type_pointer;
     cl_arg_types[1] = &ffi_type_uint32;
 
-    init_cif = malloc(sizeof(ffi_cif));
+    init_cif = calloc(sizeof(ffi_cif), 1);
 
     rv = ffi_prep_cif(init_cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer, cl_arg_types);
     if(rv != FFI_OK)

          
@@ 714,15 725,14 @@ void * quick_make_stub(void * dta, void 
     }
   }
 
-  closure = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
-             MAP_ANON | MAP_PRIVATE, -1, 0);  
+  closure = ffi_closure_alloc(sizeof(ffi_closure), &codeloc);
   
   if(closure == ((void*)-1))
   {
     Pike_error("quick_make_stub: out of memory\n");
   }
   
-  rv = ffi_prep_closure(closure, init_cif, func, dta);
+  rv = ffi_prep_closure_loc(closure, init_cif, func, dta, codeloc);
 
   if(rv != FFI_OK)
   {

          
@@ 730,11 740,13 @@ void * quick_make_stub(void * dta, void 
     Pike_error("Cannot create FFI closure.\n");
   }
 
+#if 0
   // Ensure that the closure will execute on all architectures.
   if (mprotect(closure, sizeof(closure), PROT_READ | PROT_EXEC) == -1)
   {
     Pike_error("quick_make_stub: unable to make executable\n");
   }
+#endif /* 0 */
 
   return (void *)closure;
 }

          
@@ 744,6 756,7 @@ void * quick_make_stub(void * dta, void 
 void * make_static_stub(void * dta, void * func)
 {
   static ffi_cif* init_cif = NULL;
+  void * codeloc;
   ffi_closure * closure = NULL;
   ffi_status rv;
   ffi_type** cl_arg_types;

          
@@ 752,7 765,7 @@ void * make_static_stub(void * dta, void
   
   if(init_cif == NULL)
   {
-    cl_arg_types = malloc(sizeof(ffi_type *) * 2);
+    cl_arg_types = calloc(sizeof(ffi_type *) * 2, 1);
     if(cl_arg_types == NULL)
     {
       Pike_error("quick_make_stub: out of memory\n");

          
@@ 761,7 774,7 @@ void * make_static_stub(void * dta, void
     cl_arg_types[0] = &ffi_type_pointer;
     cl_arg_types[1] = &ffi_type_uint32;
 
-    init_cif = malloc(sizeof(ffi_cif));
+    init_cif = calloc(sizeof(ffi_cif), 1);
 
     rv = ffi_prep_cif(init_cif, FFI_DEFAULT_ABI, 2, &ffi_type_void, cl_arg_types);
     if(rv != FFI_OK)

          
@@ 771,21 784,22 @@ void * make_static_stub(void * dta, void
     }
   }
 
-  closure = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
-             MAP_ANON | MAP_PRIVATE, -1, 0);  
+  closure = ffi_closure_alloc(sizeof(ffi_closure), &codeloc);
   
-  if(closure == ((void*)-1))
+  if(!closure)
   {
     Pike_error("quick_make_stub: out of memory\n");
   }
 
-  rv = ffi_prep_closure(closure, init_cif, func, dta);
+  rv = ffi_prep_closure_loc(closure, init_cif, func, dta, codeloc);
 
+#if 0
   // Ensure that the closure will execute on all architectures.
   if (mprotect(closure, sizeof(closure), PROT_READ | PROT_EXEC) == -1)
   {
     Pike_error("quick_make_stub: unable to make executable\n");
   }
+#endif /* 0 */
 
   if(rv != FFI_OK)
   {

          
@@ 805,22 819,27 @@ void * make_static_stub(void * dta, void
 void * make_static_stub(void * dta, void * func)
 {
   static ffi_cif* init_cif;
+  void * codeloc;
   ffi_closure * closure = NULL;
   ffi_status rv;
   ffi_type** cl_arg_types;
   ffi_type* cl_ret_type;
   const char* rettype;
   
-    cl_arg_types = malloc(sizeof(ffi_type *)*2);
+    cl_arg_types = calloc(sizeof(ffi_type *)*2, 1);
     if(cl_arg_types == NULL)
     {
-      Pike_error("quick_make_stub: out of memory\n");
+      Pike_error("make_static_stub: out of memory\n");
     }
     
 //    cl_arg_types[0] = &ffi_type_pointer;
     cl_arg_types[0] = &ffi_type_uint32;
 
-    init_cif = malloc(sizeof(ffi_cif));
+    init_cif = calloc(sizeof(ffi_cif), 1);
+
+    if(init_cif == NULL) {
+      Pike_error("make_static_stub: out of memory\n");
+    }
 
     rv = ffi_prep_cif(init_cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, cl_arg_types);
     if(rv != FFI_OK)

          
@@ 830,20 849,18 @@ void * make_static_stub(void * dta, void
     }
  
 // Allocate a page to hold the closure with read and write permissions.
-      if ((closure = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
-          MAP_ANON | MAP_PRIVATE, -1, 0)) == (void*)-1)
+      if (!(closure = ffi_closure_alloc(sizeof(ffi_closure), &codeloc)))
       {
 		  LOG("error mmap%s\n", "");
           // Check errno and handle the error.
       }
-//  closure = malloc(sizeof(ffi_closure));
   
   if(closure == NULL)
   {
     Pike_error("quick_make_stub: out of memory\n");
   }
   
-  rv = ffi_prep_closure(closure, init_cif, func, dta);
+  rv = ffi_prep_closure_loc(closure, init_cif, func, dta, codeloc);
 
   if(rv != FFI_OK)
   {

          
@@ 866,13 883,14 @@ void * make_static_stub(void * dta, void
 ffi_closure * make_static_stub3(void * dta, void * func)
 {
   static ffi_cif* init_cif;
+  void * codeloc;
   ffi_closure * closure = NULL;
   ffi_status rv;
   ffi_type** cl_arg_types;
   ffi_type* cl_ret_type;
   const char* rettype;
   
-    cl_arg_types = malloc(sizeof(ffi_type *)*2);
+    cl_arg_types = calloc(sizeof(ffi_type *)*2, 1);
     if(cl_arg_types == NULL)
     {
       Pike_error("quick_make_stub: out of memory\n");

          
@@ 881,7 899,7 @@ ffi_closure * make_static_stub3(void * d
 //    cl_arg_types[0] = &ffi_type_pointer;
     cl_arg_types[0] = &ffi_type_uint32;
 
-    init_cif = malloc(sizeof(ffi_cif));
+    init_cif = calloc(sizeof(ffi_cif), 1);
 
     rv = ffi_prep_cif(init_cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, cl_arg_types);
     if(rv != FFI_OK)

          
@@ 891,8 909,8 @@ ffi_closure * make_static_stub3(void * d
     }
  
 // Allocate a page to hold the closure with read and write permissions.
-      if ((closure = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
-          MAP_ANON | MAP_PRIVATE, -1, 0)) == (void*)-1)
+      if (!(closure = ffi_closure_alloc(sizeof(ffi_closure), &codeloc)
+          ) )
       {
 		  LOG("error mmap%s\n", "");
           // Check errno and handle the error.

          
@@ 904,21 922,23 @@ ffi_closure * make_static_stub3(void * d
     Pike_error("quick_make_stub: out of memory\n");
   }
   
-  rv = ffi_prep_closure(closure, init_cif, func, dta);
+  rv = ffi_prep_closure_loc(closure, init_cif, func, dta, codeloc);
 
   if(rv != FFI_OK)
   {
     free(closure);
     Pike_error("Cannot create FFI closure.\n");
   }
-  
+
+#if 0 
   // Ensure that the closure will execute on all architectures.
   if (mprotect(closure, sizeof(closure), PROT_READ | PROT_EXEC) == -1)
   {
 	  LOG("error mprotect%s\n", "");
       // Check errno and handle the error.
   }
-  
+#endif /* 0 */
+
    return closure;
 }
 

          
M mkapp.pike +2 -5
@@ 14,8 14,8 @@ array sdk_locs = ({"/Developer/SDKs", "/
 int no_embedded_pike = 0;
 
 string gcc = "clang";
-string sdk = "MacOSX10.14.sdk";
-string cc_args = "-m64 -mmacosx-version-min=10.10 -isysroot ${SDK} -F. -I/usr/local/include";
+string sdk = "MacOSX11.sdk";
+string cc_args = "-mmacosx-version-min=10.15 -isysroot ${SDK} -I/Users/hww3/pd/devel-11.0/include -F. -I/usr/local/include";
 string ld_args = "-lobjc -lpthread -framework AppKit -framework Pike -framework System -framework Foundation";
 
 int main(int argc, array(string) argv)

          
@@ 226,9 226,6 @@ char * ecs;
 JMP_BUF back;
 int num;
 int x;
-// required for console mode objective c applications 
-  objc_startCollectorThread();
-
 
 // these 2 lines set up and start the interpreter. 
 i = [OCPikeInterpreter sharedInterpreter]; 

          
M util.h +10 -0
@@ 19,6 19,7 @@ 
 #include "backend.h"
 #import <Foundation/NSAutoreleasePool.h>
 #import "OC_NSAutoreleasePoolCollector.h"
+#include <ffi/ffi.h>
 
 #if (PIKE_MAJOR_VERSION == 7 && PIKE_MINOR_VERSION == 1 && PIKE_BUILD_VERSION >= 12) || PIKE_MAJOR_VERSION > 7 || (PIKE_MAJOR_VERSION == 7 && PIKE_MINOR_VERSION > 1)
 # include "pike_error.h"

          
@@ 62,3 63,12 @@ void push_complex_result(void * result, 
 void make_complex_object(void * result, int len, char * signature);
 void push_complex_result(void * result, int len, char * signature);
 void make_complex_object(void * result, int len, char * signature);
+int push_objc_pointer_return_type(struct objc_method * method, void ** margs);
+void * svalue_to_ptr(struct svalue * sval, char * type);
+BOOL isNSNil(struct svalue * sv);
+int push_objc_types(NSMethodSignature* sig, NSInvocation* invocation);
+struct svalue * get_class_func_by_selector(struct program * prog, SEL aSelector);
+BOOL has_objc_class_method(id obj, SEL aSelector);
+char * get_signature_for_class_func(struct svalue * func, SEL selector, struct program * prog);
+BOOL has_objc_method(id obj, SEL aSelector);
+int push_objc_type(char * type, void * buf);