# HG changeset patch # User William Welliver # Date 1633505428 14400 # Wed Oct 06 03:30:28 2021 -0400 # Node ID bd63bd7a87ba1dbb0062ec712c79d1536b062143 # Parent 1658a50c89d9f1a3340d5653f10c7168ff47d7cf fix a bunch of memory leaks, correct Mapping wrapping caused by an "implicit" function definition diff --git a/OC_Mapping.m b/OC_Mapping.m --- a/OC_Mapping.m +++ b/OC_Mapping.m @@ -1,4 +1,5 @@ #include "piobjc.h" +#include "util.h" #import "OC_Mapping.h" @interface OC_MappingEnumerator : NSEnumerator @@ -29,8 +30,10 @@ struct mapping * m; self = [super init]; - if (!self) return nil; - + if (!self) { +LOG("Self is nil%s\n", ""); + return nil; + } m = [value __ObjCgetPikeMapping]; // do we need to do this? @@ -71,10 +74,10 @@ -(id)nextObject { id rv; -// LOG("[OC_MappingEnumerator nextObject]\n"); + LOG("[OC_MappingEnumerator nextObject]%s\n",""); if(!valid) { -// LOG("we're at the end of the enumerator.\n"); + LOG("we're at the end of the enumerator.%s\n", ""); return nil; } @@ -85,11 +88,11 @@ pop_stack(); return nil; } -//LOG("got the key id.\n"); +LOG("got the key id.%s\n", ""); rv = svalue_to_id(Pike_sp-1); pop_stack(); -// LOG("forwarding iterator to next object.\n"); + LOG("forwarding iterator to next object.%s\n", ""); // add_ref(iterator); apply_low(iterator, next_id, 0); @@ -102,7 +105,7 @@ } else if(SUBTYPEOF(Pike_sp[-1])) { -// LOG("at the end of the iterator.\n"); + LOG("at the end of the iterator.%s\n", ""); valid = NO; } // LOG("next value: %d", Pike_sp[-1].u.integer); @@ -128,8 +131,11 @@ self = [super init]; if (!self) return nil; + LOG("[OC_Mapping init]%s\n",""); mapping = value; add_ref(mapping); + add_ref(mapping); + add_ref(mapping); return self; } @@ -158,10 +164,11 @@ - (int)count { int r; + LOG("[OC_Mapping count]%s\n",""); ref_push_mapping(mapping); f_sizeof(1); r = Pike_sp[-1].u.integer; -// LOG("[OC_Mapping count] returns %d\n", r); + LOG("[OC_Mapping count] returns %d\n", r); pop_stack(); return r; } @@ -169,7 +176,7 @@ - (NSEnumerator*)keyEnumerator { OC_MappingEnumerator * e; -// LOG("[OC_Mapping keyEnumerator]\n"); + LOG("[OC_Mapping keyEnumerator]%s\n",""); e = [OC_MappingEnumerator newWithWrappedMapping: self type: 0]; return e; @@ -178,7 +185,7 @@ - (NSEnumerator*)objectEnumerator { OC_MappingEnumerator * e; -// LOG("[OC_Mapping objectEnumerator]\n"); + LOG("[OC_Mapping objectEnumerator]%s\n",""); e = [OC_MappingEnumerator newWithWrappedMapping: self type: 1]; return e; @@ -209,9 +216,13 @@ struct svalue * v; id vid; struct svalue * k; -// LOG("[OC_Mapping objectForKey: %s]\n", [[key description] UTF8String]); + LOG("[OC_Mapping objectForKey: %s]\n", [[key description] UTF8String]); k = low_id_to_svalue(key, 1); -//LOG("got svalue\n"); +LOG("got svalue: %d\n", sizeof(k)); +LOG("got svalue: %p\n", k); +LOG("got svalue: %p\n", k->u); +LOG("got svalue: %p\n", k->u.string); +LOG("got svalue: %s\n", k->u.string->str); // add_ref(mapping); v = low_mapping_lookup(mapping, k); //LOG("looked it up.\n"); @@ -225,4 +236,4 @@ return vid; } -@end /* implementation OC_Mapping */ \ No newline at end of file +@end /* implementation OC_Mapping */ diff --git a/ObjC.mmod b/ObjC.mmod --- a/ObjC.mmod +++ b/ObjC.mmod @@ -422,10 +422,6 @@ [THIS->pool newAutoreleasePool]; PiObjC_InitProxyRegistry(); -#if 0 - // this doesn't work in later releases of Objective-C classic. - objc_setClassHandler(piobjc_classhandler_callback); -#endif /* 0 */ global_class_cache = allocate_mapping(10); global_proxy_cache = allocate_mapping(10); @@ -619,9 +615,7 @@ struct object * pobj = NULL; struct svalue * pset = NULL; id vts; -#if !OBJC_V1 - const char * te; -#endif + char * te; LOG("new_object_setInstanceVariable(%s:%s)->%s = %s)\n", class_getName(object_getClass(object)), [[object description] UTF8String], name, [[((id)value) description ] UTF8String] ); @@ -641,11 +635,7 @@ return NULL; } -#if OBJC_V1 - if(x && x->ivar_type[0] != '@') -#else if(x && (te = ivar_getTypeEncoding(x)) && te[0] != '@') -#endif /* OBJC_V1 */ { printf("AIEEEE! We don't know how to set non-objects into Pike objects!\n"); return NULL; @@ -918,7 +908,6 @@ struct objc_ivar_list * l; int offset; -#if OBJC_V1 for(z = prog->num_identifier_references; z--;) { struct identifier * i; @@ -928,71 +917,24 @@ num_vars++; } } -#endif /* OBJC_V1 */ if(num_vars == 0) { -#if OBJC_V1 - cls->ivars = NULL; -#endif /* OBJC_V1 */ return YES; } -#if OBJC_V1 - l = malloc(sizeof(struct objc_ivar_list) + ((num_vars) * sizeof(struct objc_ivar) )); - - l->ivar_count = 0; - - if(l == NULL) - { - Pike_error("unable to allocate memory.\n"); - } - - offset = cls->super_class->instance_size; -#endif /* OBJC_V1 */ - for(z = prog->num_identifier_references; z--;) { struct identifier * i; - #if 0 - struct objc_ivar * v; - #endif i = ID_FROM_INT(prog, z); if(IDENTIFIER_IS_VARIABLE(i->identifier_flags)) { - char * ivn; - ivn = malloc(i->name->len +1); - strncpy(ivn, i->name->str, i->name->len+1); - - printf("adding variable %s\n", ivn); -#if OBJC_V1 - v = l->ivar_list + l->ivar_count; - v->ivar_name = ivn; - - offset += sizeof(struct identifier); - - v->ivar_type = @encode(id); - v->ivar_offset = offset; - l->ivar_count++; -#else - class_addIvar(cls, ivn, sizeof(struct identifier), log2(sizeof(struct identifier)), @encode(id)); -#endif /* OBJC_V1 */ - LOG("added ivar: %s!\n", ivn); + class_addIvar(cls, i->name, sizeof(id), log2(sizeof(id)), @encode(id)); + LOG("added ivar: %s!\n", i->name); } } -#if OBJC_V1 - cls->ivars = l; -/* - for(z = 0; z < cls->ivars->ivar_count; z++) - { - LOG("registered variable %s of type %s\n", cls->ivars->ivar_list[z].ivar_name, cls->ivars->ivar_list[z].ivar_type); - } -*/ - cls->instance_size = offset; -#endif /* OBJC_V1 */ - return YES; } diff --git a/PiObjCObject.m b/PiObjCObject.m --- a/PiObjCObject.m +++ b/PiObjCObject.m @@ -104,7 +104,7 @@ pobject = obj; add_ref(obj); pinstantiated = YES; -// [self retain]; + [self retain]; return self; } diff --git a/dynamic_class.m b/dynamic_class.m --- a/dynamic_class.m +++ b/dynamic_class.m @@ -1,4 +1,4 @@ -//#import +#import #import "PiObjCObject.h" #include "ffi/ffi.h" #import "OC_Array.h" @@ -244,7 +244,7 @@ method_getArgumentType(method, x, (&rtype), (size_t)10); type = &rtype; - //LOG("argument %d %s\n", x, type); + LOG("argument %d %s\n", x, type); pos = 0; while((type[pos])&&(type[pos]=='r' || type[pos] =='n' || type[pos] =='N' || type[pos]=='o' || type[pos]=='O' || type[pos] =='V') && pos < 10) pos++; @@ -341,14 +341,16 @@ break; case '@': +printf("obj!\n"); // TODO: do we need to integrate this with svalue_to_id()? if(TYPEOF(*sv)==T_OBJECT) { struct object * o = sv->u.object; - if(isNSNil(sv)) - argumentList[x] = (nil); - else + if(isNSNil(sv)) { + LOG("argument is nil\n%s", ""); + argumentList[x] = nil; + } else { Class cls; LOG("wrapping obj%s\n", ""); @@ -375,7 +377,9 @@ else if(TYPEOF(*sv) == T_MAPPING) { id rv; +LOG("encoding mapping as OC_Mapping%s\n", ""); rv = [OC_Mapping newWithPikeMapping: sv->u.mapping]; +[obj hash]; argumentList[x] = &(rv); } else if(TYPEOF(*sv) == T_INT) @@ -452,9 +456,13 @@ buf = malloc(len); if(sv) { + if(isNSNil(sv)) { + LOG("arg is nil%s\n", ""); + buf = nil; + } // TODO: we need to actually set values here, if they're passed. - } - argumentList[x] = &(buf); + } + argumentList[x] = &(buf); } break; case '[': @@ -509,6 +517,7 @@ } // free(msgResult); printf("whoo\n"); +free(cif->arg_types); free(cif); LOG("called!%s\n", ""); @@ -633,6 +642,7 @@ // now, the fun begins. if we have "pointer return" parameters, we need to get that sorted out here. if(num_pointer_return_arguments) { + LOG("have pointer return arguments\n%s",""); num_pointer_return_arguments = push_objc_pointer_return_type(method, argumentList); f_aggregate(num_pointer_return_arguments + 1); } @@ -1012,6 +1022,7 @@ } + if(ivar_list) free(ivar_list); /* next, we need to add all of the class methods. */ @@ -1070,6 +1081,7 @@ /* then, we add the instance methods. */ + free(methodList); methodList = 0; selector = 0; @@ -1111,6 +1123,8 @@ free(psig); } } + + free(methodList); LOG("checking super classes %s\n", ""); sc = class_getSuperclass(isa); @@ -1159,11 +1173,13 @@ sc = class_getSuperclass(isa); if(sc && isa == sc) { + if(methodList) free(methodList); break; } else if(sc) isa = sc; else isa = 0; + free(methodList); } free_mapping(m); diff --git a/mkapp.pike b/mkapp.pike --- a/mkapp.pike +++ b/mkapp.pike @@ -15,7 +15,7 @@ string gcc = "clang"; string sdk = "MacOSX10.14.sdk"; -string cc_args = "-mmacosx-version-min=10.10 -isysroot ${SDK} -F. -I/usr/local/include"; +string cc_args = "-m64 -mmacosx-version-min=10.10 -isysroot ${SDK} -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) diff --git a/util.h b/util.h --- a/util.h +++ b/util.h @@ -50,6 +50,8 @@ void piobjc_set_return_value(id sig, id invocation, struct svalue * svalue); id get_NSObject_from_Object(struct object *o); +struct svalue * low_id_to_svalue(id obj, int prefer_native); + char * get_signature_for_func(struct svalue * func, SEL selector, struct program * prog); id unwrap_objc_object(struct object * o); char * pike_signature_from_nsmethodsignature(id nssig, int * lenptr); diff --git a/util.m b/util.m --- a/util.m +++ b/util.m @@ -289,9 +289,7 @@ struct svalue * sv; struct object * o = NULL; LOG("low_id_to_svalue: %p\n", obj); - if(!obj) {/*LOG("low_id_to_svalue(): no object to convert!\n");*/ return NULL;} - //else - NSLog([obj description]); + if(!obj) {LOG("low_id_to_svalue(): no object to convert!\n%s", ""); return NULL;} sv = malloc(sizeof(struct svalue)); @@ -306,18 +304,25 @@ enc = NSUTF8StringEncoding; - // LOG("got a string to convert.\n"); + LOG("got a string to convert. %s\n", ""); u8s = [obj UTF8String]; str = make_shared_binary_string(u8s, [obj lengthOfBytesUsingEncoding: enc]); // free(u8s); - ref_push_string(str); + // add_ref(str); + push_string(str); f_utf8_to_string(1); - +// assign_svalue_no_free(sv, &(Pike_sp[-1])); TYPEOF(*sv) = T_STRING; SUBTYPEOF(*sv) = 0; sv->u.string = Pike_sp[-1].u.string; +// sv->u.string = str;; add_ref(sv->u.string); +LOG("str: %s\n", sv->u.string->str); pop_stack(); +LOG("str: %s\n", sv->u.string->str); +LOG("str: %p\n", sv); +LOG("str: %p\n", sv->u); +LOG("str: %d\n", sizeof(sv)); return sv; } } @@ -342,7 +347,7 @@ sv->u.mapping = m; } - else + else { o = wrap_objc_object(obj); if(o) @@ -357,7 +362,7 @@ SUBTYPEOF(*sv) = 1; sv->u.integer = 0; } - +} return sv; } @@ -804,15 +809,20 @@ case '@': { struct svalue * sval; - id * buf = (id *)(margs[arg]); - sval = id_to_svalue((*buf)); - //push_int(21); - if(sval) - push_svalue(sval); - else push_int(0); - free(buf); + id buf; + int isnull = *(int *)(margs[arg]); + printf("isnull: %d\n", isnull); + if(!isnull) { + push_int(0); + } else { + buf = (id)(margs[arg]); + sval = id_to_svalue((buf)); + if(sval) + push_svalue(sval); + else push_int(0); + // free(buf); free(sval); - + } args_pushed++; } break; @@ -1151,27 +1161,26 @@ args_pushed++; free(buf); break; - case '@': + case '@': + { // object - buf = (id)malloc(sizeof(id)); - if(buf == NULL) - Pike_error("unable to allocate memory.\n"); - [invocation getArgument: &buf atIndex: arg]; - if(buf != nil) + id b; + [invocation getArgument: &b atIndex: arg]; + if(b != nil) { - cobj = (id)buf; + cobj = (id)b; NSLog(@"description comin at ya..."); -LOG("%s\n", buf); +LOG("%s\n", b); [cobj class]; LOG("arg %d: %p\n", arg, object_getClass(cobj)); NSLog([cobj description]); sval = id_to_svalue(cobj); push_svalue(sval); free(sval); - // free(buf); } else push_int(0); args_pushed++; +} break; case '#': { @@ -1652,9 +1661,12 @@ methodList = class_copyMethodList(object_getClass(obj), &x); for (index = 0; index < x; index++) { - if(aSelector == method_getName(methodList[index])) return YES; + if(aSelector == method_getName(methodList[index])) { + free(methodList); + return YES; + } } - + free(methodList); return NO; } @@ -1669,9 +1681,12 @@ methodList = class_copyMethodList(objc_getMetaClass(object_getClassName(obj)), &x); for (index = 0; index < x; index++) { - if(aSelector == method_getName(methodList[index])) return YES; + if(aSelector == method_getName(methodList[index])) { + free(methodList); + return YES; + } } - + free(methodList); return NO; }