ObjFW  Check-in [44f5a7d029]

Overview
Comment:runtime: Make properties opaque and provide an API
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 44f5a7d02968e83a04197174d5d2d6ab3b1968a7a4e4eec875d0409e9c84f71a
User & Date: js on 2019-12-12 01:04:03
Other Links: manifest | tags
Context
2019-12-12
01:14
runtime: Make classes and protocols opaque check-in: faaf8ded07 user: js tags: trunk
01:04
runtime: Make properties opaque and provide an API check-in: 44f5a7d029 user: js tags: trunk
2019-12-09
23:08
runtime: Increase the library major version check-in: d99139b41d user: js tags: trunk
Changes

Modified src/OFIntrospection.m from [22873e1cb7] to [f35aa9485e].

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201


202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

218

219
220
221

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240







241



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
@synthesize getter = _getter, setter = _setter, iVar = _iVar;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

#if defined(OF_OBJFW_RUNTIME)
- (instancetype)of_initWithProperty: (struct objc_property *)property
{
	self = [super init];

	@try {
		_name = [[OFString alloc] initWithUTF8String: property->name];
		_attributes =
		    property->attributes | (property->extendedAttributes << 8);

		if (property->getter.name != NULL)
			_getter = [[OFString alloc]
			    initWithUTF8String: property->getter.name];
		if (property->setter.name != NULL)
			_setter = [[OFString alloc]
			    initWithUTF8String: property->setter.name];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
#elif defined(OF_APPLE_RUNTIME)
- (instancetype)of_initWithProperty: (objc_property_t)property
{
	self = [super init];

	@try {
		const char *attributes;

		_name = [[OFString alloc]
		    initWithUTF8String: property_getName(property)];

		if ((attributes = property_getAttributes(property)) == NULL)
			@throw [OFInitializationFailedException
			    exceptionWithClass: self.class];

		while (*attributes != '\0') {
			const char *start;

			switch (*attributes) {
			case 'T':
				while (*attributes != ',' &&
				    *attributes != '\0')
					attributes++;
				break;
			case 'R':
				_attributes |= OF_PROPERTY_READONLY;
				attributes++;
				break;
			case 'C':
				_attributes |= OF_PROPERTY_COPY;
				attributes++;
				break;
			case '&':
				_attributes |= OF_PROPERTY_RETAIN;
				attributes++;
				break;
			case 'N':
				_attributes |= OF_PROPERTY_NONATOMIC;
				attributes++;
				break;
			case 'G':
				start = ++attributes;

				if (_getter != nil)
					@throw [OFInitializationFailedException
					    exceptionWithClass: self.class];

				while (*attributes != ',' &&
				    *attributes != '\0')
					attributes++;

				_getter = [[OFString alloc]
				    initWithUTF8String: start
						length: attributes - start];



				break;
			case 'S':
				start = ++attributes;

				if (_setter != nil)
					@throw [OFInitializationFailedException
					    exceptionWithClass: self.class];

				while (*attributes != ',' &&
				    *attributes != '\0')
					attributes++;

				_setter = [[OFString alloc]
				    initWithUTF8String: start
						length: attributes - start];



				break;
			case 'D':
				_attributes |= OF_PROPERTY_DYNAMIC;

				attributes++;
				break;
			case 'W':
				_attributes |= OF_PROPERTY_WEAK;
				attributes++;
				break;
			case 'P':
				attributes++;
				break;
			case 'V':
				start = ++attributes;

				if (_iVar != nil)
					@throw [OFInitializationFailedException
					    exceptionWithClass: self.class];

				while (*attributes != ',' &&
				    *attributes != '\0')
					attributes++;











				_iVar = [[OFString alloc]
				    initWithUTF8String: start
						length: attributes - start];

				break;
			default:
				@throw [OFInitializationFailedException
				    exceptionWithClass: self.class];
			}

			if (*attributes != ',' && *attributes != '\0')
				@throw [OFInitializationFailedException
				    exceptionWithClass: self.class];

			if (*attributes != '\0')
				attributes++;
		}

		if (!(_attributes & OF_PROPERTY_READONLY))
			_attributes |= OF_PROPERTY_READWRITE;

		if (!(_attributes & OF_PROPERTY_COPY) &&
		    !(_attributes & OF_PROPERTY_RETAIN))







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





|




<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<

|
<
>
>
|
<
<
<
|
<
<
<

|
|
<
|

|
|
>
|
>
|
<
<
>
|
<
|
|
<
|
<
<
<
<
<
|
<
<
<

<
<
<
>
>
>
>
>
>
>

>
>
>

|
<
|
<
<
<
<
<
|
<
<
<
|
<
<







118
119
120
121
122
123
124
























125
126
127
128
129
130
131
132
133
134



135


136
























137








138
139

140
141
142



143



144
145
146

147
148
149
150
151
152
153
154


155
156

157
158

159





160



161



162
163
164
165
166
167
168
169
170
171
172
173
174

175





176



177


178
179
180
181
182
183
184
@synthesize getter = _getter, setter = _setter, iVar = _iVar;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

























- (instancetype)of_initWithProperty: (objc_property_t)property
{
	self = [super init];

	@try {
		char *value;

		_name = [[OFString alloc]
		    initWithUTF8String: property_getName(property)];




		value = property_copyAttributeValue(property, "G");


		if (value != NULL) {
























			@try {








				_getter = [[OFString alloc]
				    initWithUTF8String: value];

			} @finally {
				free(value);
			}



		}




		value = property_copyAttributeValue(property, "S");
		if (value != NULL) {

			@try {
				_setter = [[OFString alloc]
				    initWithUTF8String: value];
			} @finally {
				free(value);
			}
		}



#define BOOL_ATTRIBUTE(name, flag)					\
		value = property_copyAttributeValue(property, name);	\

		if (value != NULL) {					\
			_attributes |= flag;				\

			free(value);					\





		}







		BOOL_ATTRIBUTE("R", OF_PROPERTY_READONLY)
		BOOL_ATTRIBUTE("C", OF_PROPERTY_COPY)
		BOOL_ATTRIBUTE("&", OF_PROPERTY_RETAIN)
		BOOL_ATTRIBUTE("N", OF_PROPERTY_NONATOMIC)
		BOOL_ATTRIBUTE("D", OF_PROPERTY_DYNAMIC)
		BOOL_ATTRIBUTE("W", OF_PROPERTY_WEAK)
#undef BOOL_ATTRIBUTE

		value = property_copyAttributeValue(property, "V");
		if (value != NULL) {
			@try {
				_iVar = [[OFString alloc]
				    initWithUTF8String: value];

			} @finally {





				free(value);



			}


		}

		if (!(_attributes & OF_PROPERTY_READONLY))
			_attributes |= OF_PROPERTY_READWRITE;

		if (!(_attributes & OF_PROPERTY_COPY) &&
		    !(_attributes & OF_PROPERTY_RETAIN))
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
#else
# error Invalid ObjC runtime!
#endif

- (void)dealloc
{
	[_name release];
	[_getter release];
	[_setter release];








<
<
<







207
208
209
210
211
212
213



214
215
216
217
218
219
220
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}




- (void)dealloc
{
	[_name release];
	[_getter release];
	[_setter release];

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
- (instancetype)initWithClass: (Class)class
{
	self = [super init];

	@try {
		Method *methodList;
		Ivar *iVarList;
#if defined(OF_OBJFW_RUNTIME)
		struct objc_property_list *propertyList;
#elif defined(OF_APPLE_RUNTIME)
		objc_property_t *propertyList;
#endif
		unsigned count;
		void *pool;

		_classMethods = [[OFMutableArray alloc] init];
		_instanceMethods = [[OFMutableArray alloc] init];
		_properties = [[OFMutableArray alloc] init];
		_instanceVariables = [[OFMutableArray alloc] init];







<
<
<

<







336
337
338
339
340
341
342



343

344
345
346
347
348
349
350
- (instancetype)initWithClass: (Class)class
{
	self = [super init];

	@try {
		Method *methodList;
		Ivar *iVarList;



		objc_property_t *propertyList;

		unsigned count;
		void *pool;

		_classMethods = [[OFMutableArray alloc] init];
		_instanceMethods = [[OFMutableArray alloc] init];
		_properties = [[OFMutableArray alloc] init];
		_instanceVariables = [[OFMutableArray alloc] init];
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
				    of_initWithIVar: iVarList[i]] autorelease]];

			objc_autoreleasePoolPop(pool);
		} @finally {
			free(iVarList);
		}

#if defined(OF_OBJFW_RUNTIME)
		for (propertyList = class->properties; propertyList != NULL;
		    propertyList = propertyList->next) {
			pool = objc_autoreleasePoolPush();

			for (unsigned int i = 0; i < propertyList->count; i++)
				[_properties addObject: [[[OFProperty alloc]
				    of_initWithProperty:
				    &propertyList->properties[i]] autorelease]];

			objc_autoreleasePoolPop(pool);
		}
#elif defined(OF_APPLE_RUNTIME)
		propertyList = class_copyPropertyList(class, &count);
		@try {
			pool = objc_autoreleasePoolPush();

			for (unsigned int i = 0; i < count; i++)
				[_properties addObject: [[[OFProperty alloc]
				    of_initWithProperty: propertyList[i]]
				    autorelease]];

			objc_autoreleasePoolPop(pool);
		} @finally {
			free(propertyList);
		}
#else
# error Invalid ObjC runtime!
#endif

		[_classMethods makeImmutable];
		[_instanceMethods makeImmutable];
		[_properties makeImmutable];
		[_instanceVariables makeImmutable];
	} @catch (id e) {
		[self release];







<
<
<
<
<
<
<
<
<
<
<
<
<













<
<
<







388
389
390
391
392
393
394













395
396
397
398
399
400
401
402
403
404
405
406
407



408
409
410
411
412
413
414
				    of_initWithIVar: iVarList[i]] autorelease]];

			objc_autoreleasePoolPop(pool);
		} @finally {
			free(iVarList);
		}














		propertyList = class_copyPropertyList(class, &count);
		@try {
			pool = objc_autoreleasePoolPush();

			for (unsigned int i = 0; i < count; i++)
				[_properties addObject: [[[OFProperty alloc]
				    of_initWithProperty: propertyList[i]]
				    autorelease]];

			objc_autoreleasePoolPop(pool);
		} @finally {
			free(propertyList);
		}




		[_classMethods makeImmutable];
		[_instanceMethods makeImmutable];
		[_properties makeImmutable];
		[_instanceVariables makeImmutable];
	} @catch (id e) {
		[self release];

Modified src/runtime/ObjFWRT.h from [e3e943bde0] to [f51cebe461].

59
60
61
62
63
64
65

66
67
68
69
70
71
72
#define NO  false

typedef struct objc_class *Class;
typedef struct objc_object *id;
typedef const struct objc_selector *SEL;
typedef const struct objc_method *Method;
typedef const struct objc_ivar *Ivar;

#if !defined(__wii__) && !defined(__amigaos__)
typedef bool BOOL;
#endif
typedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull, ...);
typedef void (*objc_uncaught_exception_handler_t)(id _Nullable);
typedef void (*objc_enumeration_mutation_handler_t)(id _Nonnull);








>







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#define NO  false

typedef struct objc_class *Class;
typedef struct objc_object *id;
typedef const struct objc_selector *SEL;
typedef const struct objc_method *Method;
typedef const struct objc_ivar *Ivar;
typedef const struct objc_property *objc_property_t;
#if !defined(__wii__) && !defined(__amigaos__)
typedef bool BOOL;
#endif
typedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull, ...);
typedef void (*objc_uncaught_exception_handler_t)(id _Nullable);
typedef void (*objc_enumeration_mutation_handler_t)(id _Nonnull);

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	struct objc_dtable *_Nonnull DTable;
	Class _Nullable *_Nullable subclassList;
	void *_Nullable siblingClass;
	struct objc_protocol_list *_Nullable protocols;
	void *_Nullable GCObjectType;
	unsigned long ABIVersion;
	int32_t *_Nonnull *_Nullable ivarOffsets;
	struct objc_property_list *_Nullable properties;
};

enum objc_class_info {
	OBJC_CLASS_INFO_CLASS	    = 0x001,
	OBJC_CLASS_INFO_METACLASS   = 0x002,
	OBJC_CLASS_INFO_NEW_ABI	    = 0x010,
	OBJC_CLASS_INFO_SETUP	    = 0x100,







|







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
	struct objc_dtable *_Nonnull DTable;
	Class _Nullable *_Nullable subclassList;
	void *_Nullable siblingClass;
	struct objc_protocol_list *_Nullable protocols;
	void *_Nullable GCObjectType;
	unsigned long ABIVersion;
	int32_t *_Nonnull *_Nullable ivarOffsets;
	struct objc_property_list *_Nullable propertyList;
};

enum objc_class_info {
	OBJC_CLASS_INFO_CLASS	    = 0x001,
	OBJC_CLASS_INFO_METACLASS   = 0x002,
	OBJC_CLASS_INFO_NEW_ABI	    = 0x010,
	OBJC_CLASS_INFO_SETUP	    = 0x100,
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#ifdef __cplusplus
	Class _Nonnull class_;
#else
	Class _Nonnull class;
#endif
};

enum objc_property_attributes {
	OBJC_PROPERTY_READONLY	= 0x01,
	OBJC_PROPERTY_GETTER	= 0x02,
	OBJC_PROPERTY_ASSIGN	= 0x04,
	OBJC_PROPERTY_READWRITE	= 0x08,
	OBJC_PROPERTY_RETAIN	= 0x10,
	OBJC_PROPERTY_COPY	= 0x20,
	OBJC_PROPERTY_NONATOMIC	= 0x40,
	OBJC_PROPERTY_SETTER	= 0x80
};

enum objc_property_extended_attributes {
	OBJC_PROPERTY_SYNTHESIZE	=  0x1,
	OBJC_PROPERTY_DYNAMIC		=  0x2,
	OBJC_PROPERTY_PROTOCOL		=  0x3,
	OBJC_PROPERTY_ATOMIC		=  0x4,
	OBJC_PROPERTY_WEAK		=  0x8,
	OBJC_PROPERTY_STRONG		= 0x10,
	OBJC_PROPERTY_UNSAFE_UNRETAINED = 0x20
};

struct objc_property {
	const char *_Nonnull name;
	unsigned char attributes, extendedAttributes;
	struct {
		const char *_Nullable name;
		const char *_Nullable typeEncoding;
	} getter, setter;
};

struct objc_property_list {
	unsigned int count;
	struct objc_property_list *_Nullable next;
	struct objc_property properties[1];
};

struct objc_method_description {
	const char *_Nonnull name;
	const char *_Nonnull typeEncoding;
};

struct objc_method_description_list {
	int count;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







105
106
107
108
109
110
111




































112
113
114
115
116
117
118
#ifdef __cplusplus
	Class _Nonnull class_;
#else
	Class _Nonnull class;
#endif
};





































struct objc_method_description {
	const char *_Nonnull name;
	const char *_Nonnull typeEncoding;
};

struct objc_method_description_list {
	int count;
228
229
230
231
232
233
234





235
236
237
238
239
240
241
extern SEL _Nonnull method_getName(Method _Nonnull method);
extern const char *_Nullable method_getTypeEncoding(Method _Nonnull method);
extern Ivar _Nullable *_Nullable class_copyIvarList(Class _Nullable class_,
    unsigned int *_Nullable outCount);
extern const char *_Nonnull ivar_getName(Ivar _Nonnull ivar);
extern const char *_Nonnull ivar_getTypeEncoding(Ivar _Nonnull ivar);
extern ptrdiff_t ivar_getOffset(Ivar _Nonnull ivar);





extern void objc_exit(void);
extern _Nullable objc_uncaught_exception_handler_t
    objc_setUncaughtExceptionHandler(
    objc_uncaught_exception_handler_t _Nullable handler);
extern void objc_setForwardHandler(IMP _Nullable forward,
    IMP _Nullable stretForward);
extern void objc_setEnumerationMutationHandler(







>
>
>
>
>







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
extern SEL _Nonnull method_getName(Method _Nonnull method);
extern const char *_Nullable method_getTypeEncoding(Method _Nonnull method);
extern Ivar _Nullable *_Nullable class_copyIvarList(Class _Nullable class_,
    unsigned int *_Nullable outCount);
extern const char *_Nonnull ivar_getName(Ivar _Nonnull ivar);
extern const char *_Nonnull ivar_getTypeEncoding(Ivar _Nonnull ivar);
extern ptrdiff_t ivar_getOffset(Ivar _Nonnull ivar);
extern objc_property_t _Nullable *_Nullable class_copyPropertyList(
    Class _Nullable class_, unsigned int *_Nullable outCount);
extern const char *_Nonnull property_getName(objc_property_t _Nonnull property);
extern char *_Nullable property_copyAttributeValue(
    objc_property_t _Nonnull property, const char *_Nonnull name);
extern void objc_exit(void);
extern _Nullable objc_uncaught_exception_handler_t
    objc_setUncaughtExceptionHandler(
    objc_uncaught_exception_handler_t _Nullable handler);
extern void objc_setForwardHandler(IMP _Nullable forward,
    IMP _Nullable stretForward);
extern void objc_setEnumerationMutationHandler(

Modified src/runtime/amiga-glue.m from [fecc22bc77] to [2e81cbccc1].

663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693



























glue_ivar_getOffset PPC_PARAMS(Ivar ivar)
{
	M68K_ARG(Ivar, ivar, a0)

	return ivar_getOffset(ivar);
}

Method *
glue_class_copyMethodList PPC_PARAMS(Class class, unsigned int *outCount)
{
	M68K_ARG(Class, class, a0)
	M68K_ARG(unsigned int *, outCount, a1)

	return class_copyMethodList(class, outCount);
}

SEL
glue_method_getName PPC_PARAMS(Method method)
{
	M68K_ARG(Method, method, a0)

	return method_getName(method);
}

const char *
glue_method_getTypeEncoding PPC_PARAMS(Method method)
{
	M68K_ARG(Method, method, a0)

	return method_getTypeEncoding(method);
}


































|








|







|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
glue_ivar_getOffset PPC_PARAMS(Ivar ivar)
{
	M68K_ARG(Ivar, ivar, a0)

	return ivar_getOffset(ivar);
}

Method *__saveds
glue_class_copyMethodList PPC_PARAMS(Class class, unsigned int *outCount)
{
	M68K_ARG(Class, class, a0)
	M68K_ARG(unsigned int *, outCount, a1)

	return class_copyMethodList(class, outCount);
}

SEL __saveds
glue_method_getName PPC_PARAMS(Method method)
{
	M68K_ARG(Method, method, a0)

	return method_getName(method);
}

const char *__saveds
glue_method_getTypeEncoding PPC_PARAMS(Method method)
{
	M68K_ARG(Method, method, a0)

	return method_getTypeEncoding(method);
}

objc_property_t *__saveds
glue_class_copyPropertyList PPC_PARAMS(Class class, unsigned int *outCount)
{
	M68K_ARG(Class, class, a0)
	M68K_ARG(unsigned int *, outCount, a1)

	return class_copyPropertyList(class, outCount);
}

const char *__saveds
glue_property_getName PPC_PARAMS(objc_property_t property)
{
	M68K_ARG(objc_property_t, property, a0)

	return property_getName(property);
}

char *__saveds
glue_property_copyAttributeValue PPC_PARAMS(objc_property_t property,
    const char *name)
{
	M68K_ARG(objc_property_t, property, a0)
	M68K_ARG(const char *, name, a1)

	return property_copyAttributeValue(property, name);
}

Modified src/runtime/amiga-library.m from [ea7e18b3b9] to [9e632d2539].

131
132
133
134
135
136
137



138
139
140
141
142
143
144
extern Ivar *glue_class_copyIvarList(void);
extern const char *glue_ivar_getName(void);
extern const char *glue_ivar_getTypeEncoding(void);
extern ptrdiff_t glue_ivar_getOffset(void);
extern Method *glue_class_copyMethodList(void);
extern SEL glue_method_getName(void);
extern const char *glue_method_getTypeEncoding(void);




#ifdef OF_MORPHOS
const ULONG __abox__ = 1;
#endif
struct ExecBase *SysBase;
struct objc_libc libc;
FILE *stdout;







>
>
>







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
extern Ivar *glue_class_copyIvarList(void);
extern const char *glue_ivar_getName(void);
extern const char *glue_ivar_getTypeEncoding(void);
extern ptrdiff_t glue_ivar_getOffset(void);
extern Method *glue_class_copyMethodList(void);
extern SEL glue_method_getName(void);
extern const char *glue_method_getTypeEncoding(void);
extern objc_property_t *glue_class_copyPropertyList(void);
extern const char *glue_property_getName(void);
extern char *glue_property_copyAttributeValue(void);

#ifdef OF_MORPHOS
const ULONG __abox__ = 1;
#endif
struct ExecBase *SysBase;
struct objc_libc libc;
FILE *stdout;
645
646
647
648
649
650
651



652
653
654
655
656
657
658
	(CONST_APTR)glue_class_copyIvarList,
	(CONST_APTR)glue_ivar_getName,
	(CONST_APTR)glue_ivar_getTypeEncoding,
	(CONST_APTR)glue_ivar_getOffset,
	(CONST_APTR)glue_class_copyMethodList,
	(CONST_APTR)glue_method_getName,
	(CONST_APTR)glue_method_getTypeEncoding,



	(CONST_APTR)-1,
#ifdef OF_MORPHOS
	(CONST_APTR)FUNCARRAY_END
#endif
};
#pragma GCC diagnostic pop








>
>
>







648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
	(CONST_APTR)glue_class_copyIvarList,
	(CONST_APTR)glue_ivar_getName,
	(CONST_APTR)glue_ivar_getTypeEncoding,
	(CONST_APTR)glue_ivar_getOffset,
	(CONST_APTR)glue_class_copyMethodList,
	(CONST_APTR)glue_method_getName,
	(CONST_APTR)glue_method_getTypeEncoding,
	(CONST_APTR)glue_class_copyPropertyList,
	(CONST_APTR)glue_property_getName,
	(CONST_APTR)glue_property_copyAttributeValue,
	(CONST_APTR)-1,
#ifdef OF_MORPHOS
	(CONST_APTR)FUNCARRAY_END
#endif
};
#pragma GCC diagnostic pop

Modified src/runtime/amigaos3.sfd from [2e99ad65a3] to [313504d85b].

74
75
76
77
78
79
80



81
Ivar _Nullable *_Nullable glue_class_copyIvarList(Class _Nullable class_, unsigned int *_Nullable outCount)(a0,a1)
const char *_Nonnull glue_ivar_getName(Ivar _Nonnull ivar)(a0)
const char *_Nonnull glue_ivar_getTypeEncoding(Ivar _Nonnull ivar)(a0)
ptrdiff_t glue_ivar_getOffset(Ivar _Nonnull ivar)(a0)
Method _Nullable *_Nullable glue_class_copyMethodList(Class _Nullable class_, unsigned int *_Nullable outCount)(a0,a1)
SEL _Nonnull glue_method_getName(Method _Nonnull method)(a0)
const char *_Nullable glue_method_getTypeEncoding(Method _Nonnull method)(a0)



==end







>
>
>

74
75
76
77
78
79
80
81
82
83
84
Ivar _Nullable *_Nullable glue_class_copyIvarList(Class _Nullable class_, unsigned int *_Nullable outCount)(a0,a1)
const char *_Nonnull glue_ivar_getName(Ivar _Nonnull ivar)(a0)
const char *_Nonnull glue_ivar_getTypeEncoding(Ivar _Nonnull ivar)(a0)
ptrdiff_t glue_ivar_getOffset(Ivar _Nonnull ivar)(a0)
Method _Nullable *_Nullable glue_class_copyMethodList(Class _Nullable class_, unsigned int *_Nullable outCount)(a0,a1)
SEL _Nonnull glue_method_getName(Method _Nonnull method)(a0)
const char *_Nullable glue_method_getTypeEncoding(Method _Nonnull method)(a0)
objc_property_t _Nullable *_Nullable glue_class_copyPropertyList(Class _Nullable class_, unsigned int *_Nullable outCount)(a0,a1)
const char *_Nonnull glue_property_getName(objc_property_t _Nonnull property)(a0)
char *_Nullable glue_property_copyAttributeValue(objc_property_t _Nonnull property, const char *_Nonnull name)(a0,a1)
==end

Modified src/runtime/linklib/linklib.m from [2d8b4b35eb] to [962890f13f].

629
630
631
632
633
634
635


















}

const char *
method_getTypeEncoding(Method method)
{
	return glue_method_getTypeEncoding(method);
}

























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
}

const char *
method_getTypeEncoding(Method method)
{
	return glue_method_getTypeEncoding(method);
}

objc_property_t *
class_copyPropertyList(Class class, unsigned int *outCount)
{
	return glue_class_copyPropertyList(class, outCount);
}

const char *
property_getName(objc_property_t property)
{
	return glue_property_getName(property);
}

char *
property_copyAttributeValue(objc_property_t property, const char *name)
{
	return glue_property_copyAttributeValue(property, name);
}

Modified src/runtime/morphos-clib.h from [1eba9b9866] to [c0d4505658].

68
69
70
71
72
73
74



Ivar *glue_class_copyIvarList(Class class_, unsigned int *outCount);
const char *glue_ivar_getName(Ivar ivar);
const char *glue_ivar_getTypeEncoding(Ivar ivar);
ptrdiff_t glue_ivar_getOffset(Ivar ivar);
Method *glue_class_copyMethodList(Class class_, unsigned int *outCount);
SEL glue_method_getName(Method method);
const char *glue_method_getTypeEncoding(Method method);










>
>
>
68
69
70
71
72
73
74
75
76
77
Ivar *glue_class_copyIvarList(Class class_, unsigned int *outCount);
const char *glue_ivar_getName(Ivar ivar);
const char *glue_ivar_getTypeEncoding(Ivar ivar);
ptrdiff_t glue_ivar_getOffset(Ivar ivar);
Method *glue_class_copyMethodList(Class class_, unsigned int *outCount);
SEL glue_method_getName(Method method);
const char *glue_method_getTypeEncoding(Method method);
objc_property_t *glue_class_copyPropertyList(Class class_, unsigned int *outCount);
const char *glue_property_getName(objc_property_t property);
char *glue_property_copyAttributeValue(objc_property_t property, const char *name);

Modified src/runtime/morphos.fd from [4df918228d] to [946400c8ab].

70
71
72
73
74
75
76



77
glue_class_copyIvarList(class_,outCount)(sysv,r12base)
glue_ivar_getName(ivar)(sysv,r12base)
glue_ivar_getTypeEncoding(ivar)(sysv,r12base)
glue_ivar_getOffset(ivar)(sysv,r12base)
glue_class_copyMethodList(class_,outCount)(sysv,r12base)
glue_method_getName(method)(sysv,r12base)
glue_method_getTypeEncoding(method)(sysv,r12base)



##end







>
>
>

70
71
72
73
74
75
76
77
78
79
80
glue_class_copyIvarList(class_,outCount)(sysv,r12base)
glue_ivar_getName(ivar)(sysv,r12base)
glue_ivar_getTypeEncoding(ivar)(sysv,r12base)
glue_ivar_getOffset(ivar)(sysv,r12base)
glue_class_copyMethodList(class_,outCount)(sysv,r12base)
glue_method_getName(method)(sysv,r12base)
glue_method_getTypeEncoding(method)(sysv,r12base)
glue_class_copyPropertyList(class_,outCount)(sysv,r12base)
glue_property_getName(property)(sysv,r12base)
glue_property_copyAttributeValue(property,name)(sysv,r12base)
##end

Modified src/runtime/private.h from [81f62cf3b8] to [a5bc0aa2aa].

63
64
65
66
67
68
69




































70
71
72
73
74
75
76
	unsigned int offset;
};

struct objc_ivar_list {
	unsigned int count;
	struct objc_ivar ivars[1];
};





































struct objc_static_instances {
	const char *_Nonnull className;
	id _Nullable instances[1];
};

struct objc_symtab {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	unsigned int offset;
};

struct objc_ivar_list {
	unsigned int count;
	struct objc_ivar ivars[1];
};

enum objc_property_attributes {
	OBJC_PROPERTY_READONLY	= 0x01,
	OBJC_PROPERTY_GETTER	= 0x02,
	OBJC_PROPERTY_ASSIGN	= 0x04,
	OBJC_PROPERTY_READWRITE	= 0x08,
	OBJC_PROPERTY_RETAIN	= 0x10,
	OBJC_PROPERTY_COPY	= 0x20,
	OBJC_PROPERTY_NONATOMIC	= 0x40,
	OBJC_PROPERTY_SETTER	= 0x80
};

enum objc_property_extended_attributes {
	OBJC_PROPERTY_SYNTHESIZED	=  0x1,
	OBJC_PROPERTY_DYNAMIC		=  0x2,
	OBJC_PROPERTY_PROTOCOL		=  0x3,
	OBJC_PROPERTY_ATOMIC		=  0x4,
	OBJC_PROPERTY_WEAK		=  0x8,
	OBJC_PROPERTY_STRONG		= 0x10,
	OBJC_PROPERTY_UNSAFE_UNRETAINED = 0x20
};

struct objc_property {
	const char *_Nonnull name;
	unsigned char attributes, extendedAttributes;
	struct {
		const char *_Nullable name;
		const char *_Nullable typeEncoding;
	} getter, setter;
};

struct objc_property_list {
	unsigned int count;
	struct objc_property_list *_Nullable next;
	struct objc_property properties[1];
};

struct objc_static_instances {
	const char *_Nonnull className;
	id _Nullable instances[1];
};

struct objc_symtab {

Modified src/runtime/property.m from [af06feb764] to [b52cba63b9].

152
153
154
155
156
157
158









































































































#endif

		return;
	}

	memcpy(dest, src, size);
}
















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#endif

		return;
	}

	memcpy(dest, src, size);
}

objc_property_t *
class_copyPropertyList(Class class, unsigned int *outCount)
{
	unsigned int i, count;
	struct objc_property_list *iter;
	objc_property_t *properties;

	if (class == Nil) {
		if (outCount != NULL)
			*outCount = 0;

		return NULL;
	}

	objc_global_mutex_lock();

	count = 0;
	if (class->info & OBJC_CLASS_INFO_NEW_ABI)
		for (iter = class->propertyList; iter != NULL;
		    iter = iter->next)
			count += iter->count;

	if (count == 0) {
		if (outCount != NULL)
			*outCount = 0;

		objc_global_mutex_unlock();
		return NULL;
	}

	properties = malloc((count + 1) * sizeof(objc_property_t));
	if (properties == NULL)
		OBJC_ERROR("Not enough memory to copy properties");

	i = 0;
	for (iter = class->propertyList; iter != NULL; iter = iter->next)
		for (unsigned int j = 0; j < iter->count; j++)
			properties[i++] = &iter->properties[j];
	OF_ENSURE(i == count);
	properties[count] = NULL;

	if (outCount != NULL)
		*outCount = count;

	objc_global_mutex_unlock();

	return properties;
}

const char *
property_getName(objc_property_t property)
{
	return property->name;
}

char *
property_copyAttributeValue(objc_property_t property, const char *name)
{
	char *ret = NULL;
	bool nullIsError = false;

	if (strlen(name) != 1)
		return NULL;

	switch (*name) {
	case 'T':
		ret = of_strdup(property->getter.typeEncoding);
		nullIsError = true;
		break;
	case 'G':
		if (property->attributes & OBJC_PROPERTY_GETTER) {
			ret = of_strdup(property->getter.name);
			nullIsError = true;
		}
		break;
	case 'S':
		if (property->attributes & OBJC_PROPERTY_SETTER) {
			ret = of_strdup(property->setter.name);
			nullIsError = true;
		}
		break;
#define BOOL_CASE(name, field, flag)		\
	case name:				\
		if (property->field & flag) {	\
			ret = calloc(1, 1);	\
			nullIsError = true;	\
		}				\
		break;

	BOOL_CASE('R', attributes, OBJC_PROPERTY_READONLY)
	BOOL_CASE('C', attributes, OBJC_PROPERTY_COPY)
	BOOL_CASE('&', attributes, OBJC_PROPERTY_RETAIN)
	BOOL_CASE('N', attributes, OBJC_PROPERTY_NONATOMIC)
	BOOL_CASE('D', extendedAttributes, OBJC_PROPERTY_DYNAMIC)
	BOOL_CASE('W', extendedAttributes, OBJC_PROPERTY_WEAK)
#undef BOOL_CASE
	}

	if (nullIsError && ret == NULL)
		OBJC_ERROR("Not enough memory to copy property attribute "
		    "value");

	return ret;
}