summaryrefslogtreecommitdiff
path: root/Objective-C/PyObjC/objc-runtime-apple.h
blob: 8d050a111e05b1fbdafe966bff396dd1875c9a3d (plain)
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
128
129
130
131
132
133
134
135
136
137
/* Copyright (c) 1996,97,98 by Lele Gaifax.  All Rights Reserved
 * Copyright (c) 2003 Ronald Oussoren
 *
 * This software may be used and distributed freely for any purpose
 * provided that this notice is included unchanged on any and all
 * copies. The author does not warrant or guarantee this software in
 * any way.
 *
 * This file is part of the PyObjC package.
 *
 * RCSfile: objc_support.h,v
 * Revision: 1.16
 * Date: 1998/08/18 15:35:57
 *
 * Created Tue Sep 10 14:11:38 1996.
 */

#ifndef PyObjC_RUNTIME_APPLE_H
#define PyObjC_RUNTIME_APPLE_H

#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>

#include <objc/objc-runtime.h>
#include <objc/Protocol.h>

#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>

static inline int 
PyObjCRT_SameSEL(SEL a, SEL b)
{
	return a == b;
}

static inline const char* 
PyObjCRT_SELName(SEL sel)
{
	return sel_getName(sel);
}

static inline SEL 
PyObjCRT_SELUID(const char* str)
{
	return sel_getUid(str);
}

static inline Class 
PyObjCRT_LookUpClass(const char* name)
{
	return objc_lookUpClass(name);
}

static inline struct objc_method_list *
PyObjCRT_NextMethodList(Class c, void ** p)
{
	return class_nextMethodList(c, p);
}

static inline void 
PyObjCRT_InitMethod(Method m, SEL name, const char* types, IMP imp)
{
	memset(m, 0, sizeof(*m));
	m->method_name = name;
	m->method_types = strdup((char*)types);
	m->method_imp = imp;
}

static inline void
PyObjCRT_ClassAddMethodList(Class cls, struct objc_method_list* lst)
{
	class_addMethods(cls, lst);
}


extern struct objc_method_list* PyObjCRT_AllocMethodList(ssize_t);
extern struct objc_protocol_list* PyObjCRT_AllocProtocolList(ssize_t);

typedef Method PyObjCRT_Method_t;
typedef Ivar PyObjCRT_Ivar_t;

#define GETISA(c)       ((c)->isa)

#define RECEIVER(c)     ((c).receiver)

#define _C_CONST    'r'
#define _C_IN       'n'
#define _C_INOUT    'N'
#define _C_OUT      'o'
#define _C_BYCOPY   'O'
#define _C_ONEWAY   'V'
#define _C_LNGLNG   'q'
#define _C_ULNGLNG  'Q'
#define _C_BOOL	    'B'		/* (Objective-)C++ 'bool' */


/* Return a number that is likely to change when the method list changes,
 * and is cheap to compute.
 */
static inline int
objc_methodlist_magic(Class cls)
{
  int res = 0; 
  int cnt = 0;
    
  /* This is the documented way of enumerating the method list.  It
   * is slower than the obvious way, but does not explode under
   * esoteric situations.
   */ 
  void *iterator = NULL;
  struct objc_method_list *mlist;

  if (cls == NULL) return -1;

  while ( (mlist = class_nextMethodList( cls, &iterator )) != NULL ) {
    res += mlist->method_count;
    cnt++;
  }

  return (cnt << 16) | (res & 0xFFFF);
}

static inline const char *
get_selector_encoding (id self, SEL sel)
{
	struct objc_method* m = class_getInstanceMethod(self->isa, sel);

	if (!m) {
		return NULL;
	} else {
		return m->method_types;
	}
}

#endif /* PyObjC_RUNTIME_APPLE_H */