# HG changeset patch # User William Welliver # Date 1638468609 18000 # Thu Dec 02 13:10:09 2021 -0500 # Node ID a4c02da90c3ac469ff8b9643feef82fe02c2a19d # Parent 5dbbca4cf464083ae8b8610530fd98fdfb923239 # Parent 27a9a024079de89251599e8e27d6fa800ed3c8ff merging diff --git a/AppKit.mmod b/AppKit.mmod --- a/AppKit.mmod +++ b/AppKit.mmod @@ -68,6 +68,7 @@ #import #import #import + #import #define _GNU_SOURCE #define THIS_IS_APPKIT 1 diff --git a/Makefile.in b/Makefile.in --- a/Makefile.in +++ b/Makefile.in @@ -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 diff --git a/PiObjCObject.m b/PiObjCObject.m --- a/PiObjCObject.m +++ b/PiObjCObject.m @@ -75,6 +75,7 @@ #import #import #import "PiObjCObject.h" +#include "proxy-registry.h" extern int async_error_mode; void dispatch_pike_method(struct object * pobject, SEL sel, NSInvocation * anInvocation); diff --git a/dynamic_class.m b/dynamic_class.m --- a/dynamic_class.m +++ b/dynamic_class.m @@ -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 @@ 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 @@ 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; diff --git a/method_dispatch.m b/method_dispatch.m --- a/method_dispatch.m +++ b/method_dispatch.m @@ -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 #import #import #include #include "piobjc.h" +#include 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 @@ /* 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 @@ } /* 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 @@ 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 @@ 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 @@ 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 @@ } } - 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 @@ 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_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 @@ 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 @@ 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 @@ } } - 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 @@ 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 @@ { 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 @@ 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 @@ } } - 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 @@ } } - 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 @@ 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_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 @@ 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 @@ 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 @@ } } - 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 @@ 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 * 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 @@ 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 @@ 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 @@ } } - 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 @@ 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 * 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 @@ 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 @@ 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 @@ } } - 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 * 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 @@ } // 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 @@ 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 @@ // 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 @@ } // 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 @@ 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; } diff --git a/mkapp.pike b/mkapp.pike --- a/mkapp.pike +++ b/mkapp.pike @@ -14,8 +14,8 @@ 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 @@ 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]; diff --git a/util.h b/util.h --- a/util.h +++ b/util.h @@ -19,6 +19,7 @@ #include "backend.h" #import #import "OC_NSAutoreleasePoolCollector.h" +#include #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 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);