~ubuntu-branches/ubuntu/karmic/gnustep-base/karmic

« back to all changes in this revision

Viewing changes to Source/callframe.m

  • Committer: Bazaar Package Importer
  • Author(s): Eric Heintzmann
  • Date: 2005-04-17 00:14:38 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050417001438-enf0y07c9tku85z1
Tags: 1.10.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/** callframe.m - Wrapper/Objective-C interface for ffcall function interface
2
2
 
3
3
   Copyright (C) 2000, Free Software Foundation, Inc.
4
 
   
 
4
 
5
5
   Written by:  Adam Fedor <fedor@gnu.org>
6
6
   Created: Nov 2000
7
 
   
 
7
 
8
8
   This file is part of the GNUstep Base Library.
9
9
 
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.
14
 
   
 
14
 
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.
19
 
   
 
19
 
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.
23
 
   */ 
 
23
   */
24
24
 
25
 
#include <config.h>
 
25
#include "config.h"
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"
 
31
 
 
32
#ifdef HAVE_MALLOC_H
 
33
#include <malloc.h>
 
34
#endif
31
35
 
32
36
#if defined(ALPHA) || (defined(MIPS) && (_MIPS_SIM == _ABIN32))
33
37
typedef long long smallret_t;
35
39
typedef int smallret_t;
36
40
#endif
37
41
 
38
 
/* Return the number of arguments that the method MTH expects.  Note
39
 
   that all methods need two implicit arguments `self' and `_cmd'.  
40
 
   From mframe.m */
41
 
extern int method_types_get_number_of_arguments (const char *type);
42
 
 
43
 
extern BOOL sel_types_match(const char* t1, const char* t2);
44
 
 
45
42
callframe_t *
46
43
callframe_from_info (NSArgumentInfo *info, int numargs, void **retval)
47
44
{
48
45
  unsigned      size = sizeof(callframe_t);
49
46
  unsigned      align = __alignof(double);
50
 
  unsigned      offset;
 
47
  unsigned      offset = 0;
51
48
  void          *buf;
52
49
  int           i;
53
50
  callframe_t   *cframe;
161
158
} NSInvocation_t;
162
159
 
163
160
/*-------------------------------------------------------------------------*/
164
 
/* Functions for handling sending and receiving messages accross a 
 
161
/* Functions for handling sending and receiving messages accross a
165
162
   connection
166
163
*/
167
164
 
230
227
                void(*decoder)(DOContext*),
231
228
                void(*encoder)(DOContext*))
232
229
{
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. */
286
283
  {
287
284
    Method m;
288
285
    m = class_getInstanceMethod(object->isa, selector);
289
 
    if (!m) 
 
286
    if (!m)
290
287
      abort();
291
288
    type = m->method_types;
292
289
  }
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));
309
306
 
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],
313
310
                               &retval);
314
311
  ctxt->datToFree = cframe;
315
312
 
423
420
          (*decoder) (ctxt);
424
421
        }
425
422
    }
426
 
  /* End of the for() loop that enumerates the method's arguments. */
 
423
  /* End of the for () loop that enumerates the method's arguments. */
427
424
  ctxt->type = 0;
428
425
  ctxt->datum = 0;
429
426
  (*decoder) (ctxt);
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);
488
485
             so we can see what it is a pointer to. */
489
486
          tmptype++;
490
487
          ctxt->type = tmptype;
491
 
          ctxt->datum = *(void**)ctxt->datum;
 
488
          ctxt->datum = *(void**)retval;
492
489
        }
493
490
      else
494
491
        {
531
528
              ctxt->flags = flags;
532
529
              ctxt->datum = callframe_arg_addr(cframe, argnum);
533
530
 
534
 
              if (*tmptype == _C_PTR) 
 
531
              if (*tmptype == _C_PTR)
535
532
                {
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
561
558
 
562
559
/* callframe_build_return()
563
560
 
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.
567
564
 
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.  */
571
568
 
572
569
void
573
570
callframe_build_return (NSInvocation *inv,
574
 
                     const char *type, 
 
571
                     const char *type,
575
572
                     BOOL out_parameters,
576
573
                     void(*decoder)(DOContext *ctxt),
577
574
                     DOContext *ctxt)
594
591
 
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],
598
595
                               &retval);
599
596
  ctxt->datToFree = cframe;
600
597
 
616
613
 
617
614
      /* If there is a return value, decode it, and put it in retval. */
618
615
      if (*tmptype != _C_VOID || (flags & _F_ONEWAY) == 0)
619
 
        {         
 
616
        {       
620
617
          ctxt->type = tmptype;
621
618
          ctxt->datum = retval;
622
619
          ctxt->flags = flags;
632
629
                tmptype++;
633
630
                retLength = objc_sizeof_type(tmptype);
634
631
                /* Allocate memory to hold the value we're pointing to. */
635
 
                *(void**)retval = 
 
632
                *(void**)retval =
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. */
645
642
              }
646
643
              break;
647
644
 
648
 
            case _C_STRUCT_B: 
 
645
            case _C_STRUCT_B:
649
646
            case _C_UNION_B:
650
647
            case _C_ARY_B:
651
648
              /* Decode the return value into the memory we allocated. */
652
649
              (*decoder) (ctxt);
653
650
              break;
654
651
 
655
 
            case _C_FLT: 
 
652
            case _C_FLT:
656
653
            case _C_DBL:
657
654
              (*decoder) (ctxt);
658
655
              break;
679
676
        {
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++)
685
682
            {
699
696
              ctxt->flags = flags;
700
697
 
701
698
              if (*tmptype == _C_PTR
702
 
                  && ((flags & _F_OUT) || !(flags & _F_IN)))
 
699
                && ((flags & _F_OUT) || !(flags & _F_IN)))
703
700
                {
704
701
                  void *ptr;
 
702
 
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
710
708
                  tmptype++;
711
709
                  ctxt->type = tmptype;
712
710
 
713
 
                  (*decoder) (ctxt);
714
 
                  /* Copy the pointed-to data back to the original
715
 
                     pointer */
 
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));
 
714
                  ctxt->datum = ptr;
 
715
 
 
716
                  (*decoder) (ctxt);
718
717
                }
719
718
              else if (*tmptype == _C_CHARPTR
720
719
                && ((flags & _F_OUT) || !(flags & _F_IN)))