1
1
/** callframe.m - Wrapper/Objective-C interface for ffcall function interface
3
3
Copyright (C) 2000, Free Software Foundation, Inc.
5
5
Written by: Adam Fedor <fedor@gnu.org>
8
8
This file is part of the GNUstep Base Library.
10
10
This library is free software; you can redistribute it and/or
11
11
modify it under the terms of the GNU Library General Public
12
12
License as published by the Free Software Foundation; either
13
13
version 2 of the License, or (at your option) any later version.
15
15
This library is distributed in the hope that it will be useful,
16
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
18
Library General Public License for more details.
20
20
You should have received a copy of the GNU Library General Public
21
21
License along with this library; if not, write to the Free
22
22
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
26
26
#include <stdlib.h>
27
27
#include "callframe.h"
28
#include <Foundation/NSException.h>
29
#include <Foundation/NSData.h>
30
#include <base/GSInvocation.h>
28
#include "Foundation/NSException.h"
29
#include "Foundation/NSData.h"
30
#include "GSInvocation.h"
32
36
#if defined(ALPHA) || (defined(MIPS) && (_MIPS_SIM == _ABIN32))
33
37
typedef long long smallret_t;
35
39
typedef int smallret_t;
38
/* Return the number of arguments that the method MTH expects. Note
39
that all methods need two implicit arguments `self' and `_cmd'.
41
extern int method_types_get_number_of_arguments (const char *type);
43
extern BOOL sel_types_match(const char* t1, const char* t2);
46
43
callframe_from_info (NSArgumentInfo *info, int numargs, void **retval)
48
45
unsigned size = sizeof(callframe_t);
49
46
unsigned align = __alignof(double);
53
50
callframe_t *cframe;
230
227
void(*decoder)(DOContext*),
231
228
void(*encoder)(DOContext*))
233
/* The method type string obtained from the target's OBJC_METHOD
230
/* The method type string obtained from the target's OBJC_METHOD
234
231
structure for the selector we're sending. */
235
232
const char *type;
236
233
/* A pointer into the local variable TYPE string. */
305
302
/* Make sure we successfully got the method type, and that its
306
303
types match the ENCODED_TYPES. */
307
304
NSCParameterAssert (type);
308
NSCParameterAssert (sel_types_match(encoded_types, type));
305
NSCParameterAssert (GSSelectorTypesMatch(encoded_types, type));
310
307
/* Build the cif frame */
311
308
sig = [NSMethodSignature signatureWithObjCTypes: type];
312
cframe = callframe_from_info([sig methodInfo], [sig numberOfArguments],
309
cframe = callframe_from_info([sig methodInfo], [sig numberOfArguments],
314
311
ctxt->datToFree = cframe;
436
433
NSCParameterAssert (method_implementation);
437
434
/* Do it! Send the message to the target, and get the return value
438
435
in retval. We need to encode any pass-by-reference info */
439
inv = (NSInvocation_t *)NSAllocateObject([NSInvocation class], 0,
436
inv = (NSInvocation_t *)NSAllocateObject([NSInvocation class], 0,
440
437
NSDefaultMallocZone());
441
438
inv->_retval = retval;
442
439
inv->_selector = selector;
444
441
inv->_info = [sig methodInfo];
445
442
inv->_numArgs = [sig numberOfArguments];
446
443
ctxt->objToFree = (id)inv;
447
GSFFCallInvokeWithTargetAndImp((NSInvocation *)inv, object,
444
GSFFCallInvokeWithTargetAndImp((NSInvocation *)inv, object,
448
445
method_implementation);
449
446
ctxt->objToFree = nil;
450
447
NSDeallocateObject((NSInvocation *)inv);
531
528
ctxt->flags = flags;
532
529
ctxt->datum = callframe_arg_addr(cframe, argnum);
534
if (*tmptype == _C_PTR)
531
if (*tmptype == _C_PTR)
536
533
/* The argument is a pointer (to a non-char), and the
537
534
pointer's value is qualified as an OUT parameter, or
562
559
/* callframe_build_return()
564
This function decodes the values returned from a method call,
561
This function decodes the values returned from a method call,
565
562
sets up the invocation with the return value, and updates the
566
pass-by-reference arguments.
563
pass-by-reference arguments.
568
The callback function is finally called with the 'type' set to a nul pointer
565
The callback function is finally called with the 'type' set to a null pointer
569
566
to tell it that the return value and all return parameters have been
570
567
dealt with. This permits the function to do any tidying up necessary. */
573
570
callframe_build_return (NSInvocation *inv,
575
572
BOOL out_parameters,
576
573
void(*decoder)(DOContext *ctxt),
595
592
/* Build the call frame */
596
593
sig = [NSMethodSignature signatureWithObjCTypes: type];
597
cframe = callframe_from_info([sig methodInfo], [sig numberOfArguments],
594
cframe = callframe_from_info([sig methodInfo], [sig numberOfArguments],
599
596
ctxt->datToFree = cframe;
633
630
retLength = objc_sizeof_type(tmptype);
634
631
/* Allocate memory to hold the value we're pointing to. */
636
633
NSZoneCalloc(NSDefaultMallocZone(), retLength, 1);
637
634
/* We are responsible for making sure this memory gets free'd
638
635
eventually. Ask NSData class to autorelease it. */
680
677
/* Step through all the arguments, finding the ones that were
681
678
passed by reference. */
682
for (tmptype = objc_skip_argspec (tmptype), argnum = 0;
679
for (tmptype = objc_skip_argspec (tmptype), argnum = 0;
683
680
*tmptype != '\0';
684
681
tmptype = objc_skip_argspec (tmptype), argnum++)
699
696
ctxt->flags = flags;
701
698
if (*tmptype == _C_PTR
702
&& ((flags & _F_OUT) || !(flags & _F_IN)))
699
&& ((flags & _F_OUT) || !(flags & _F_IN)))
705
703
/* The argument is a pointer (to a non-char), and
706
704
the pointer's value is qualified as an OUT
707
705
parameter, or it not explicitly qualified as an
711
709
ctxt->type = tmptype;
714
/* Copy the pointed-to data back to the original
711
/* Use the original pointer to find the buffer
712
* to store the returned data */
716
713
[inv getArgument: &ptr atIndex: argnum];
717
memcpy(ptr, datum, objc_sizeof_type(tmptype));
719
718
else if (*tmptype == _C_CHARPTR
720
719
&& ((flags & _F_OUT) || !(flags & _F_IN)))