File: forward-1.m

package info (click to toggle)
gcc-arm-none-eabi 15%3A14.2.rel1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,099,328 kB
  • sloc: cpp: 3,627,108; ansic: 2,571,498; ada: 834,230; f90: 235,082; makefile: 79,231; asm: 74,984; xml: 51,692; exp: 39,736; sh: 33,298; objc: 15,629; python: 15,069; fortran: 14,429; pascal: 7,003; awk: 5,070; perl: 3,106; ml: 285; lisp: 253; lex: 204; haskell: 135
file content (127 lines) | stat: -rw-r--r-- 3,077 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* { dg-do run } */
/* See if -forward:: is able to work. */
/* { dg-skip-if "Needs OBJC2 Implementation" { *-*-darwin8* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
/* { dg-additional-options "-Wl,-framework,Foundation" { target *-*-darwin* } } */
#include <stdio.h>
#include <stdlib.h>

/* Versions of the runtime after 10.13 no longer support the original
   'forward:' mechanism, so we make a stripped down representation of
   NSInvocation and need to link with -framework Foundation.  */
#if __NEXT_RUNTIME__
@class  NSInvocation, NSMethodSignature;
# include "../../objc-obj-c++-shared/F-NSObject.h"
@interface NSInvocation : NSObject
+ (NSInvocation *)invocationWithMethodSignature:(NSMethodSignature *)sig;
@property SEL selector;
- (void)invoke;
- (void)invokeWithTarget:(id)target;
@end
# define OBJECT NSObject
#else
#include "../../objc-obj-c++-shared/TestsuiteObject.m"
#define OBJECT TestsuiteObject
#endif

#define VALUETOUSE 1234567890

id forwarder, receiver;

@interface Forwarder : OBJECT
{
    id receiver;
}

-initWithReceiver:theReceiver;
#if __NEXT_RUNTIME__
- (void)forwardInvocation:(NSInvocation *)anInvocation;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
#endif

@end

@interface Receiver : OBJECT
{
    int foo;
}
-display;
-initWithFoo:(int)theFoo;
@end

@implementation Receiver

-initWithFoo: (int)theFoo
{
    foo = theFoo;
    return self;
}

-display
{
  printf ("Executing display\n");
    /* Check to see if we are really the reciever. */
    if (self != receiver)
        abort ();
    /* And the value of foo is set correctly. */
    if (foo != VALUETOUSE)
      abort ();
    return self;
}

@end

@implementation Forwarder
-initWithReceiver: theReceiver
{
    [super init];
    receiver = theReceiver;
    return self;
}

#if __NEXT_RUNTIME__
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSel
{
 return [receiver methodSignatureForSelector:aSel];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    if ([receiver respondsToSelector:[anInvocation selector]]) {
        [anInvocation invokeWithTarget:receiver];
    }
    else {
    }
}
#else
-(void *) forward:(SEL)theSel : (void *)theArgFrame
{
  /* If we have a reciever try to perform on that object */
    if (receiver)
      {
	/* Simple forward that works for methods with no
	   arguments.  */
	typedef id (*method_with_no_args) (id receiver, SEL _cmd);
	Method method = class_getInstanceMethod (object_getClass (receiver),
						 theSel);
	method_with_no_args imp = (method_with_no_args)(method_getImplementation
							(method));
	return (*imp)(receiver, theSel);
      }

    /* Normally you'd emit an error here.  */
    printf ("Unrecognized selector\n");
    return NULL;
}
#endif

@end
int main()
{
    /* Init the reciever. */
    receiver = [[Receiver alloc] initWithFoo: VALUETOUSE];
    /* Init the fowarder. */
    forwarder = [[Forwarder alloc] initWithReceiver: receiver];
    /* Call display on the forwarder which in turns calls display on
       the reciever. */
    [forwarder display];
    exit(0);
}