Index: GSFFIInvocation.m =================================================================== RCS file: /cvsroot/gnustep/gnustep/core/base/Source/GSFFIInvocation.m,v retrieving revision 1.29 diff -u -r1.29 GSFFIInvocation.m --- GSFFIInvocation.m 2 Sep 2004 16:35:44 -0000 1.29 +++ GSFFIInvocation.m 9 Dec 2004 22:59:52 -0000 @@ -35,6 +35,31 @@ #define INLINE inline #endif +static void dump_cframe(cifframe_t *c) +{ + int i; + printf("** cframe=%p\n",c); + printf(" cif=%i %i %i %08x\n", + c->cif.abi, + c->cif.nargs, + c->cif.bytes, + c->cif.flags); + printf(" nargs=%i\n",c->nargs); + printf(" arg_types=%p\n",c->arg_types); + printf(" rvalue=%p\n",c->rvalue); + printf(" values=%p\n",c->values); + for (i=0;inargs;i++) + { + printf(" %i type=%p (%i %i %i) values=%p\n", + i,c->arg_types[i], + c->arg_types[i]->size, + c->arg_types[i]->alignment, + c->arg_types[i]->type, + c->values[i]); + } +} + + typedef struct _NSInvocation_t { @defs(NSInvocation) } NSInvocation_t; @@ -142,6 +167,7 @@ static IMP gs_objc_msg_forward (SEL sel) { +//printf("%s sel=%s\n",__PRETTY_FUNCTION__,sel_get_name(sel)); const char *sel_type; cifframe_t *cframe; ffi_closure *cclosure; @@ -179,7 +205,8 @@ /* Note: We malloc cframe here, but it's passed to GSFFIInvocationCallback where it becomes owned by the callback invocation, so we don't have to worry about freeing it */ - cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments], NULL); + cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments]); +//dump_cframe(cframe); /* Autorelease the closure through GSAutoreleasedBuffer */ cclosure = (ffi_closure *)GSAutoreleasedBuffer(sizeof(ffi_closure)); if (cframe == NULL || cclosure == NULL) @@ -192,6 +219,7 @@ [NSException raise: NSGenericException format: @"Preping closure"]; } +//printf("%s return\n",__PRETTY_FUNCTION__); return (IMP)cclosure; } @@ -202,6 +230,7 @@ - (id) initWithArgframe: (arglist_t)frame selector: (SEL)aSelector { +//printf("%s\n",__PRETTY_FUNCTION__); /* We should never get here */ NSDeallocateObject(self); [NSException raise: NSInternalInconsistencyException @@ -214,6 +243,7 @@ */ - (id) initWithMethodSignature: (NSMethodSignature*)aSignature { +//printf("%s sig=%@\n",__PRETTY_FUNCTION__,aSignature); if (aSignature == nil) { RELEASE(self); @@ -222,7 +252,9 @@ _sig = RETAIN(aSignature); _numArgs = [aSignature numberOfArguments]; _info = [aSignature methodInfo]; - _cframe = cifframe_from_info(_info, _numArgs, &_retval); + _cframe = cifframe_from_info(_info, _numArgs); + _retval = ((cifframe_t *)_cframe)->rvalue; +//printf("%s return %@\n",__PRETTY_FUNCTION__,self); return self; } @@ -235,14 +267,19 @@ frame: (cifframe_t *)frame signature: (NSMethodSignature*)aSignature { +//printf("%s\n",__PRETTY_FUNCTION__); int i; _sig = RETAIN(aSignature); _numArgs = [aSignature numberOfArguments]; _info = [aSignature methodInfo]; _cframe = frame; + _retval = ((cifframe_t *)_cframe)->rvalue; ((cifframe_t *)_cframe)->cif = *cif; +//dump_cframe(_cframe); -#if MFRAME_STRUCT_BYREF +#if 0 +#if MFRAME_STRUCT_BYREF +//printf("fix up\n"); /* Fix up some of the values. Do this on all processors that pass structs by reference. Is there an automatic way to determine this? */ for (i = 0; i < ((cifframe_t *)_cframe)->nargs; i++) @@ -261,9 +298,26 @@ } } #else +//printf("set values to %p\n",vals); ((cifframe_t *)_cframe)->values = vals; #endif - _retval = retp; +#endif + for (i = 0; i < ((cifframe_t *)_cframe)->nargs; i++) + { + memcpy(((cifframe_t *)_cframe)->values[i], vals[i], + ((cifframe_t *)_cframe)->arg_types[i]->size); + } + +// _retval = retp; +if (((cifframe_t *)_cframe)->cif.rtype->type != FFI_TYPE_VOID) +{ +/*printf("_retval=%p size=%i retp=%p\n", + _retval, ((cifframe_t *)_cframe)->cif.rtype->size, retp); +printf("type=%i\n",((cifframe_t *)_cframe)->cif.rtype->type);*/ + memcpy(_retval, retp, ((cifframe_t *)_cframe)->cif.rtype->size); +//printf(" %p %p\n",*(void **)_retval,*(void **)retp); +} +//printf("%s return %@\n",__PRETTY_FUNCTION__,self); return self; } @@ -274,6 +328,7 @@ void GSFFIInvokeWithTargetAndImp(NSInvocation *_inv, id anObject, IMP imp) { +//printf("%s object %@\n",__PRETTY_FUNCTION__,anObject); NSInvocation_t *inv = (NSInvocation_t*)_inv; /* Do it */ @@ -283,8 +338,21 @@ /* Don't decode the return value here (?) */ } +void print_info(NSArgumentInfo *i) +{ + printf("** NSArgumentInfo %p\n",i); + printf(" offset=%i\n",i->offset); + printf(" size=%i\n",i->size); + printf(" type=%s\n",i->type); + printf(" align=%i\n",i->align); + printf(" qual=%i\n",i->qual); + printf(" isReg=%i\n",i->isReg); +} + - (void) invokeWithTarget: (id)anObject { +//printf("%s self=%@\n",__PRETTY_FUNCTION__,self); +//dump_cframe(_cframe); id old_target; IMP imp; @@ -309,11 +377,29 @@ * _cframe. */ old_target = RETAIN(_target); +/*printf("old_target=%@ anObject=%@ selector=%s\n", + old_target,anObject,sel_get_name(_selector));*/ [self setTarget: anObject]; +//printf("set target/selector\n"); + +/* NSMethodSignature *_sig; + void *_retval;*/ + +//printf("_numArgs=%i\n",_numArgs); + +//printf("_cframe=%p _info=%p\n",_cframe,_info); +//dump_cframe(_cframe); +/*print_info(&_info[0]); +print_info(&_info[1]); +print_info(&_info[2]); +print_info(&_info[3]);*/ + cifframe_set_arg((cifframe_t *)_cframe, 0, &_target, _info[1].size); +//printf("1\n"); cifframe_set_arg((cifframe_t *)_cframe, 1, &_selector, _info[2].size); +//printf("to super?\n"); if (_sendToSuper == YES) { Super s; @@ -327,6 +413,7 @@ } else { +//printf("silly 'fast??' lookup\n"); GSMethod method; method = GSGetMethod((GSObjCIsInstance(_target) ? GSObjCClass(_target) @@ -359,6 +446,7 @@ - (void*) returnFrame: (arglist_t)argFrame { +//printf("%s\n",__PRETTY_FUNCTION__); return _retval; } @end @@ -408,6 +496,11 @@ void GSFFIInvocationCallback(ffi_cif *cif, void *retp, void **args, void *user) { +//printf("%s\n",__PRETTY_FUNCTION__); +//printf("args=%p\n",args); +//printf("retp=%p\n",retp); +//printf(" %p %p %p\n",args[0],args[1],args[2]); +//printf(" %p %p %p\n",*(void **)(args[0]),*(void **)(args[1]),*(void **)(args[2])); id obj; SEL selector; GSFFIInvocation *invocation; @@ -417,6 +510,8 @@ obj = *(id *)args[0]; selector = *(SEL *)args[1]; +//printf("obj=%@ sel=%s\n",obj,sel_get_name(selector)); + fwdInvMethod = gs_method_for_receiver_and_selector (obj, @selector (forwardInvocation:)); @@ -480,9 +575,9 @@ selector = gs_find_best_typed_sel (selector); if (sel_get_type (selector) != 0) - { - sig = [NSMethodSignature signatureWithObjCTypes: sel_get_type(selector)]; - } + { + sig = [NSMethodSignature signatureWithObjCTypes: sel_get_type(selector)]; + } } if (sig == nil) @@ -518,6 +613,13 @@ this since the return value (retp) really belongs to the closure not the invocation so it will be demallocd at the end of this call */ +//printf("time to return\n"); +//printf("retp=%p *retp=%p\n",retp,*(void **)retp); +{ + cifframe_t *c=(cifframe_t *)user; +//printf("_retval=%p *_retval=%p\n",c->rvalue,*(void **)c->rvalue); + memcpy(retp,c->rvalue,c->cif.rtype->size); +} if ([sig methodReturnType] && *[sig methodReturnType] == _C_ID && ((NSInvocation_t *)invocation)->_validReturn == YES) { @@ -528,6 +630,7 @@ /* We need to (re)encode the return type for it's trip back. */ if (retp) cifframe_encode_arg([sig methodReturnType], retp); +//printf("%s return\n",__PRETTY_FUNCTION__); } @implementation NSInvocation (DistantCoding) @@ -536,6 +639,7 @@ to send over the wire */ - (BOOL) encodeWithDistantCoder: (NSCoder*)coder passPointers: (BOOL)passp { +//printf("%s\n",__PRETTY_FUNCTION__); int i; BOOL out_parameters = NO; const char *type = [_sig methodType]; Index: GSInvocation.h =================================================================== RCS file: /cvsroot/gnustep/gnustep/core/base/Source/GSInvocation.h,v retrieving revision 1.1 diff -u -r1.1 GSInvocation.h --- GSInvocation.h 31 Jul 2003 23:49:30 -0000 1.1 +++ GSInvocation.h 9 Dec 2004 22:59:52 -0000 @@ -59,6 +59,6 @@ }\ } while (0) -#define RETAIN_RETURN_VALUE do { if (*_info[0].type == _C_ID) RETAIN (*(id*) _retval);} while (0) +#define RETAIN_RETURN_VALUE do { if (*_info[0].type == _C_ID) RETAIN (*(id*) _retval);} while (0) #endif Index: cifframe.h =================================================================== RCS file: /cvsroot/gnustep/gnustep/core/base/Source/cifframe.h,v retrieving revision 1.8 diff -u -r1.8 cifframe.h --- cifframe.h 4 Jun 2004 03:37:12 -0000 1.8 +++ cifframe.h 9 Dec 2004 22:59:53 -0000 @@ -34,10 +34,10 @@ int nargs; ffi_type **arg_types; void **values; + void *rvalue; } cifframe_t; -extern cifframe_t *cifframe_from_info (NSArgumentInfo *info, int numargs, - void **retval); +extern cifframe_t *cifframe_from_info (NSArgumentInfo *info, int numargs); extern void cifframe_set_arg(cifframe_t *cframe, int index, void *buffer, int size); extern void cifframe_get_arg(cifframe_t *cframe, int index, void *buffer, Index: cifframe.m =================================================================== RCS file: /cvsroot/gnustep/gnustep/core/base/Source/cifframe.m,v retrieving revision 1.17 diff -u -r1.17 cifframe.m --- cifframe.m 19 Aug 2004 16:19:48 -0000 1.17 +++ cifframe.m 9 Dec 2004 22:59:54 -0000 @@ -114,9 +114,14 @@ } +void print_info(NSArgumentInfo *i); + cifframe_t * -cifframe_from_info (NSArgumentInfo *info, int numargs, void **retval) +cifframe_from_info (NSArgumentInfo *info, int numargs) { +//printf("%s\n",__PRETTY_FUNCTION__); +//printf("%s info=%p numargs=%i\n",__PRETTY_FUNCTION__,info,numargs); +//print_info(info+0); unsigned size = sizeof(cifframe_t); unsigned align = __alignof(double); unsigned type_offset = 0; @@ -132,6 +137,7 @@ them in our cifframe so we don't leak memory. Or maybe we could cache structure types? */ rtype = cifframe_type(info[0].type, NULL); +//printf("got rtype %p type %i size %i\n",rtype,rtype->type,rtype->size); for (i = 0; i < numargs; i++) { arg_types[i] = cifframe_type(info[i+1].type, NULL); @@ -190,9 +196,10 @@ else full += MAX(rtype->size, sizeof(smallret_t)); cframe = buf = NSZoneCalloc(NSDefaultMallocZone(), full, 1); - if (cframe && retval) + if (cframe) { - *retval = buf + pos; + cframe->rvalue = buf + pos; +// *retval = buf + pos; } } else @@ -243,8 +250,11 @@ void cifframe_set_arg(cifframe_t *cframe, int index, void *buffer, int size) { +//printf("set_arg cframe=%p index=%i nargs=%i\n",cframe,index,cframe->nargs); +//printf("buf=%p size=%i\n",buffer,size); if (index < 0 || index >= cframe->nargs) return; +//printf("copy to %p\n",cframe->values[index]); memcpy(cframe->values[index], buffer, size); } @@ -646,7 +656,6 @@ NSInvocation_t *inv; /* Signature information */ NSMethodSignature *sig; - void *retval; const char *encoded_types = ctxt->type; /* Decode the object, (which is always the first argument to a method), @@ -699,8 +708,7 @@ /* Build the cif frame */ sig = [NSMethodSignature signatureWithObjCTypes: type]; - cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments], - &retval); + cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments]); ctxt->datToFree = cframe; /* Put OBJECT and SELECTOR into the ARGFRAME. */ @@ -828,7 +836,7 @@ in retval. We need to encode any pass-by-reference info */ inv = (NSInvocation_t *)NSAllocateObject([NSInvocation class], 0, NSDefaultMallocZone()); - inv->_retval = retval; + inv->_retval = cframe->rvalue; inv->_selector = selector; inv->_cframe = cframe; inv->_info = [sig methodInfo]; @@ -878,13 +886,13 @@ so we can see what it is a pointer to. */ tmptype++; ctxt->type = tmptype; - ctxt->datum = *(void**)retval; + ctxt->datum = *(void**)cframe->rvalue; } else { - cifframe_decode_arg(tmptype, retval); + cifframe_decode_arg(tmptype, cframe->rvalue); ctxt->type = tmptype; - ctxt->datum = retval; + ctxt->datum = cframe->rvalue; } /* Encode the value that was pointed to. */ (*encoder) (ctxt); @@ -985,8 +993,8 @@ /* Build the cif frame */ sig = [NSMethodSignature signatureWithObjCTypes: type]; - cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments], - &retval); + cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments]); + retval = cframe->rvalue; ctxt->datToFree = cframe; /* Get the return type qualifier flags, and the return type. */