Fix but in forwarded object return

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@15985 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fedor 2003-02-17 05:06:02 +00:00
parent 1f7b60b370
commit c5a763be4c
4 changed files with 27 additions and 20 deletions

View file

@ -3,12 +3,8 @@
* Version 1.5.2 * Version 1.5.2
* Documentation: Update. * Documentation: Update.
* Source/cifframe.m (cifframe_from_info): Include retval in * Source/GSFFIInvocation.m (GSFFIInvocationCallback): Autorelease
cifframe_t struct not as pass-back argument. and invalidate the return value object before returning.
* Source/GSFFIInvocation.m (-initWithMethodSignature:): Get retval
from cifframe.
(-initWithCallback:...): Idem.
(GSFFIInvocationCallback): Set return pointer in closure.
2003-02-16 Richard Frith-Macdonald <rfm@gnu.org> 2003-02-16 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -169,7 +169,7 @@ static IMP gs_objc_msg_forward (SEL sel)
/* Note: We malloc cframe here, but it's passed to GSFFIInvocationCallback /* 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 where it becomes owned by the callback invocation, so we don't have to
worry about freeing it */ worry about freeing it */
cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments]); cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments], NULL);
/* Autorelease the closure through fastMallocBuffer */ /* Autorelease the closure through fastMallocBuffer */
cclosure = (ffi_closure *)_fastMallocBuffer(sizeof(ffi_closure)); cclosure = (ffi_closure *)_fastMallocBuffer(sizeof(ffi_closure));
if (cframe == NULL || cclosure == NULL) if (cframe == NULL || cclosure == NULL)
@ -212,8 +212,7 @@ static IMP gs_objc_msg_forward (SEL sel)
_sig = RETAIN(aSignature); _sig = RETAIN(aSignature);
_numArgs = [aSignature numberOfArguments]; _numArgs = [aSignature numberOfArguments];
_info = [aSignature methodInfo]; _info = [aSignature methodInfo];
_cframe = cifframe_from_info(_info, _numArgs); _cframe = cifframe_from_info(_info, _numArgs, &_retval);
_retval = ((cifframe_t *)_cframe)->retval;
return self; return self;
} }
@ -221,6 +220,7 @@ static IMP gs_objc_msg_forward (SEL sel)
the callback. The cifframe was allocated by the forwarding function, the callback. The cifframe was allocated by the forwarding function,
but we own it now so we can free it */ but we own it now so we can free it */
- (id) initWithCallback: (ffi_cif *)cif - (id) initWithCallback: (ffi_cif *)cif
returnp: (void *)retp
values: (void **)vals values: (void **)vals
frame: (cifframe_t *)frame frame: (cifframe_t *)frame
signature: (NSMethodSignature*)aSignature signature: (NSMethodSignature*)aSignature
@ -253,7 +253,7 @@ static IMP gs_objc_msg_forward (SEL sel)
#else #else
((cifframe_t *)_cframe)->values = vals; ((cifframe_t *)_cframe)->values = vals;
#endif #endif
_retval = ((cifframe_t *)_cframe)->retval; _retval = retp;
return self; return self;
} }
@ -389,6 +389,7 @@ GSFFIInvocationCallback(ffi_cif *cif, void *retp, void **args, void *user)
NSStringFromSelector(selector)); NSStringFromSelector(selector));
invocation = [[GSFFIInvocation alloc] initWithCallback: cif invocation = [[GSFFIInvocation alloc] initWithCallback: cif
returnp: retp
values: args values: args
frame: user frame: user
signature: sig]; signature: sig];
@ -406,8 +407,18 @@ GSFFIInvocationCallback(ffi_cif *cif, void *retp, void **args, void *user)
* so the line below is somewhat faster. */ * so the line below is somewhat faster. */
fwdInvMethod->method_imp (obj, fwdInvMethod->method_name, invocation); fwdInvMethod->method_imp (obj, fwdInvMethod->method_name, invocation);
/* Autorelease the invocation's return value (if it's an object) and
mark it as invalid, so it won't be released later. We have to do
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
*/
if ([sig methodReturnType] && *[sig methodReturnType] == _C_ID)
{
AUTORELEASE(*(id *)retp);
invocation->_validReturn = NO;
}
/* We need to (re)encode the return type for it's trip back. */ /* We need to (re)encode the return type for it's trip back. */
retp = [invocation returnFrame: NULL];
if (retp) if (retp)
cifframe_encode_arg([sig methodReturnType], retp); cifframe_encode_arg([sig methodReturnType], retp);
} }

View file

@ -34,10 +34,10 @@ typedef struct _cifframe_t {
int nargs; int nargs;
ffi_type **arg_types; ffi_type **arg_types;
void **values; void **values;
void *retval;
} cifframe_t; } cifframe_t;
extern cifframe_t *cifframe_from_info (NSArgumentInfo *info, int numargs); extern cifframe_t *cifframe_from_info (NSArgumentInfo *info, int numargs,
void **retval);
extern void cifframe_set_arg(cifframe_t *cframe, int index, void *buffer, extern void cifframe_set_arg(cifframe_t *cframe, int index, void *buffer,
int size); int size);
extern void cifframe_get_arg(cifframe_t *cframe, int index, void *buffer, extern void cifframe_get_arg(cifframe_t *cframe, int index, void *buffer,

View file

@ -116,7 +116,7 @@ cifframe_guess_struct_size(ffi_type *stype)
cifframe_t * cifframe_t *
cifframe_from_info (NSArgumentInfo *info, int numargs) cifframe_from_info (NSArgumentInfo *info, int numargs, void **retval)
{ {
unsigned size = sizeof(cifframe_t); unsigned size = sizeof(cifframe_t);
unsigned align = __alignof(double); unsigned align = __alignof(double);
@ -191,9 +191,9 @@ cifframe_from_info (NSArgumentInfo *info, int numargs)
else else
full += MAX(rtype->size, sizeof(smallret_t)); full += MAX(rtype->size, sizeof(smallret_t));
cframe = buf = NSZoneCalloc(NSDefaultMallocZone(), full, 1); cframe = buf = NSZoneCalloc(NSDefaultMallocZone(), full, 1);
if (cframe) if (cframe && retval)
{ {
cframe->retval = buf + pos; *retval = buf + pos;
} }
} }
else else
@ -700,8 +700,8 @@ cifframe_do_call (DOContext *ctxt,
/* Build the cif frame */ /* Build the cif frame */
sig = [NSMethodSignature signatureWithObjCTypes: type]; sig = [NSMethodSignature signatureWithObjCTypes: type];
cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments]); cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments],
retval = cframe->retval; &retval);
ctxt->datToFree = cframe; ctxt->datToFree = cframe;
/* Put OBJECT and SELECTOR into the ARGFRAME. */ /* Put OBJECT and SELECTOR into the ARGFRAME. */
@ -986,8 +986,8 @@ cifframe_build_return (NSInvocation *inv,
/* Build the cif frame */ /* Build the cif frame */
sig = [NSMethodSignature signatureWithObjCTypes: type]; sig = [NSMethodSignature signatureWithObjCTypes: type];
cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments]); cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments],
retval = cframe->retval; &retval);
ctxt->datToFree = cframe; ctxt->datToFree = cframe;
/* Get the return type qualifier flags, and the return type. */ /* Get the return type qualifier flags, and the return type. */