ObjFW  Check-in [c6d2de4312]

Overview
Comment:runtime: Remove duplicate structs for ABI
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: c6d2de43122566d44477dabdc9c772e9eb8aa6aadd4ab0ebf6493688d77e16f4
User & Date: js on 2019-11-24 22:23:10
Other Links: manifest | tags
Context
2019-11-24
22:42
Fix a memory leak check-in: 7ed1bdc642 user: js tags: trunk
22:23
runtime: Remove duplicate structs for ABI check-in: c6d2de4312 user: js tags: trunk
20:54
Minor style fix check-in: f90224870e user: js tags: trunk
Changes

Modified src/OFBlock.m from [acebb38475] to [814d0106d2].

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
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







-
-
-
+
+
+


-
-
-
+
+
+
+


-
-
-
+
+
+


-
-
-
+
+
+
+


-
-
-
+
+
+


-
-
-
+
+
+
+




-
+










-
-
+
+







@protocol RetainRelease
- (instancetype)retain;
- (void)release;
@end

#ifdef OF_OBJFW_RUNTIME
/* Begin of ObjC module */
static struct objc_abi_class _NSConcreteStackBlock_metaclass = {
	(struct objc_abi_class *)(void *)"OFBlock", "OFBlock", "OFStackBlock",
	8, OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_abi_class), NULL, NULL
static struct objc_class _NSConcreteStackBlock_metaclass = {
	(Class)(void *)"OFObject", (Class)(void *)"OFBlock", "OFStackBlock", 8,
	OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_class), NULL, NULL
};

struct objc_abi_class _NSConcreteStackBlock = {
	&_NSConcreteStackBlock_metaclass, "OFBlock", "OFStackBlock",
	8, OBJC_CLASS_INFO_CLASS, sizeof(of_block_literal_t), NULL, NULL
struct objc_class _NSConcreteStackBlock = {
	&_NSConcreteStackBlock_metaclass, (Class)(void *)"OFBlock",
	"OFStackBlock", 8, OBJC_CLASS_INFO_CLASS, sizeof(of_block_literal_t),
	NULL, NULL
};

static struct objc_abi_class _NSConcreteGlobalBlock_metaclass = {
	(struct objc_abi_class *)(void *)"OFBlock", "OFBlock", "OFGlobalBlock",
	8, OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_abi_class), NULL, NULL
static struct objc_class _NSConcreteGlobalBlock_metaclass = {
	(Class)(void *)"OFObject", (Class)(void *)"OFBlock", "OFGlobalBlock", 8,
	OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_class), NULL, NULL
};

struct objc_abi_class _NSConcreteGlobalBlock = {
	&_NSConcreteGlobalBlock_metaclass, "OFBlock", "OFGlobalBlock",
	8, OBJC_CLASS_INFO_CLASS, sizeof(of_block_literal_t), NULL, NULL
struct objc_class _NSConcreteGlobalBlock = {
	&_NSConcreteGlobalBlock_metaclass, (Class)(void *)"OFBlock",
	"OFGlobalBlock", 8, OBJC_CLASS_INFO_CLASS, sizeof(of_block_literal_t),
	NULL, NULL
};

static struct objc_abi_class _NSConcreteMallocBlock_metaclass = {
	(struct objc_abi_class *)(void *)"OFBlock", "OFBlock", "OFMallocBlock",
	8, OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_abi_class), NULL, NULL
static struct objc_class _NSConcreteMallocBlock_metaclass = {
	(Class)(void *)"OFObject", (Class)(void *)"OFBlock", "OFMallocBlock", 8,
	OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_class), NULL, NULL
};

struct objc_abi_class _NSConcreteMallocBlock = {
	&_NSConcreteMallocBlock_metaclass, "OFBlock", "OFMallocBlock",
	8, OBJC_CLASS_INFO_CLASS, sizeof(of_block_literal_t), NULL, NULL
struct objc_class _NSConcreteMallocBlock = {
	&_NSConcreteMallocBlock_metaclass, (Class)(void *)"OFBlock",
	"OFMallocBlock", 8, OBJC_CLASS_INFO_CLASS, sizeof(of_block_literal_t),
	NULL, NULL
};

static struct {
	unsigned long unknown;
	struct objc_abi_selector *selectorRefs;
	struct objc_selector *selectorRefs;
	uint16_t classDefsCount, categoryDefsCount;
	void *defs[4];
} symtab = {
	0, NULL, 3, 0,
	{
		&_NSConcreteStackBlock, &_NSConcreteGlobalBlock,
		&_NSConcreteMallocBlock, NULL
	}
};

static struct objc_abi_module module = {
	8, sizeof(module), NULL, (struct objc_abi_symtab *)&symtab
static struct objc_module module = {
	8, sizeof(module), NULL, (struct objc_symtab *)&symtab
};

OF_CONSTRUCTOR()
{
	__objc_exec_class(&module);
}
/* End of ObjC module */

Modified src/block.h from [e2b05adf4f] to [e8b856e116].

46
47
48
49
50
51
52
53
54


55
56
57
58
59
60
61
46
47
48
49
50
51
52


53
54
55
56
57
58
59
60
61







-
-
+
+







# if defined(OF_WINDOWS) && \
    (defined(OF_NO_SHARED) || defined(OF_COMPILING_OBJFW))
/*
 * Clang has implicit declarations for these, but they are dllimport. When
 * compiling ObjFW itself or using it as a static library, these need to be
 * dllexport. Interestingly, this still works when using it as a shared library.
 */
extern __declspec(dllexport) struct objc_abi_class _NSConcreteStackBlock;
extern __declspec(dllexport) struct objc_abi_class _NSConcreteGlobalBlock;
extern __declspec(dllexport) struct objc_class _NSConcreteStackBlock;
extern __declspec(dllexport) struct objc_class _NSConcreteGlobalBlock;
extern __declspec(dllexport) void _Block_object_assign(void *, const void *,
    const int);
extern __declspec(dllexport) void _Block_object_dispose(const void *,
    const int);
# endif
#ifdef __cplusplus
}

Modified src/runtime/ObjFWRT.h from [7fa4aef07e] to [48a67ef497].

57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71







-
+







#define nil (id _Null_unspecified)0
#define YES true
#define NO  false

typedef struct objc_class *Class;
typedef struct objc_object *id;
typedef const struct objc_selector *SEL;
typedef struct objc_ivar *Ivar;
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);

267
268
269
270
271
272
273

274

275
276
277
278
279
280
281
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282







+
-
+








/*
 * Used by the compiler, but can also be called manually.
 *
 * These declarations are also required to prevent Clang's implicit
 * declarations which include __declspec(dllimport) on Windows.
 */
struct objc_module;
extern void __objc_exec_class(void *_Nonnull module);
extern void __objc_exec_class(struct objc_module *_Nonnull module);
extern IMP _Nonnull objc_msg_lookup(id _Nullable object, SEL _Nonnull selector);
extern IMP _Nonnull objc_msg_lookup_stret(id _Nullable object,
    SEL _Nonnull selector);
extern IMP _Nonnull objc_msg_lookup_super(struct objc_super *_Nonnull super,
    SEL _Nonnull selector);
extern IMP _Nonnull objc_msg_lookup_super_stret(
    struct objc_super *_Nonnull super, SEL _Nonnull selector);

Modified src/runtime/amiga-glue.m from [91f4bad4cf] to [53f74ff653].

51
52
53
54
55
56
57
58

59
60

61
62
63
64
65
66
67
51
52
53
54
55
56
57

58
59

60
61
62
63
64
65
66
67







-
+

-
+







	M68K_ARG(FILE *, stdout_, a1)
	M68K_ARG(FILE *, stderr_, a2)

	return objc_init(version, libc, stdout_, stderr_);
}

void __saveds
glue___objc_exec_class PPC_PARAMS(void *module)
glue___objc_exec_class PPC_PARAMS(struct objc_module *module)
{
	M68K_ARG(void *, module, a0)
	M68K_ARG(struct objc_module *, module, a0)

	__objc_exec_class(module);
}

IMP __saveds
glue_objc_msg_lookup PPC_PARAMS(id object, SEL selector)
{

Modified src/runtime/amigaos3.sfd from [af633e4379] to [dd36c99661].

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17









-
+







==base _ObjFWRTBase
==basetype struct Library *
==libname objfwrt68k.library
==bias 30
==public
* Functions that are only for the linklib.
bool glue_objc_init(unsigned int version, struct objc_libc *libc, FILE *stdout, FILE *stderr)(d0,a0,a1,a2)
* These have a built-in declaration in the compiler that does not use the
* registers and thus always need glue.
void glue___objc_exec_class(void *_Nonnull module)(a0)
void glue___objc_exec_class(struct objc_module *_Nonnull module)(a0)
IMP _Nonnull glue_objc_msg_lookup(id _Nullable object, SEL _Nonnull selector)(a0,a1)
IMP _Nonnull glue_objc_msg_lookup_stret(id _Nullable object, SEL _Nonnull selector)(a0,a1)
IMP _Nonnull glue_objc_msg_lookup_super(struct objc_super *_Nonnull super, SEL _Nonnull selector)(a0,a1)
IMP _Nonnull glue_objc_msg_lookup_super_stret(struct objc_super *_Nonnull super, SEL _Nonnull selector)(a0,a1)
Class _Nullable glue_objc_lookUpClass(const char *_Nonnull name)(a0)
Class _Nullable glue_objc_getClass(const char *_Nonnull name)(a0)
Class _Nonnull glue_objc_getRequiredClass(const char *_Nonnull name)(a0)

Modified src/runtime/category.m from [5c4513a7b1] to [3c4cc24bfa].

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
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







-
+

-
-
+
+
+
+
-
-
-
+
+
-

-
+
-
-
-
+
+
-



-
+

-
+






-
+



-
+





-
+

















-
+
-














-
+

-
-
+
+








#import "ObjFWRT.h"
#import "private.h"

static struct objc_hashtable *categoriesMap = NULL;

static void
registerSelectors(struct objc_abi_category *category)
registerSelectors(struct objc_category *category)
{
	for (struct objc_abi_method_list *methodList =
	    category->instanceMethods; methodList != NULL;
	struct objc_method_list *iter;
	unsigned int i;

	for (iter = category->instanceMethods; iter != NULL; iter = iter->next)
	    methodList = methodList->next)
		for (unsigned int i = 0; i < methodList->count; i++)
			objc_register_selector((struct objc_abi_selector *)
		for (i = 0; i < iter->count; i++)
			objc_register_selector(&iter->methods[i].selector);
			    &methodList->methods[i]);

	for (struct objc_abi_method_list *methodList = category->classMethods;
	for (iter = category->classMethods; iter != NULL; iter = iter->next)
	    methodList != NULL; methodList = methodList->next)
		for (unsigned int i = 0; i < methodList->count; i++)
			objc_register_selector((struct objc_abi_selector *)
		for (i = 0; i < iter->count; i++)
			objc_register_selector(&iter->methods[i].selector);
			    &methodList->methods[i]);
}

static void
registerCategory(struct objc_abi_category *category)
registerCategory(struct objc_category *category)
{
	struct objc_abi_category **categories;
	struct objc_category **categories;
	Class class = objc_classname_to_class(category->className, false);

	if (categoriesMap == NULL)
		categoriesMap = objc_hashtable_new(
		    objc_hash_string, objc_equal_string, 2);

	categories = (struct objc_abi_category **)objc_hashtable_get(
	categories = (struct objc_category **)objc_hashtable_get(
	    categoriesMap, category->className);

	if (categories != NULL) {
		struct objc_abi_category **newCategories;
		struct objc_category **newCategories;
		size_t i;

		for (i = 0; categories[i] != NULL; i++);

		if ((newCategories = realloc(categories,
		    (i + 2) * sizeof(struct objc_abi_category *))) == NULL)
		    (i + 2) * sizeof(*categories))) == NULL)
			OBJC_ERROR("Not enough memory for category %s of "
			    "class %s!", category->categoryName,
			    category->className);

		newCategories[i] = category;
		newCategories[i + 1] = NULL;
		objc_hashtable_set(categoriesMap, category->className,
		    newCategories);

		if (class != Nil && class->info & OBJC_CLASS_INFO_SETUP) {
			objc_update_dtable(class);
			objc_update_dtable(class->isa);
		}

		return;
	}

	if ((categories = malloc(
	if ((categories = malloc(2 * sizeof(*categories))) == NULL)
	    2 * sizeof(struct objc_abi_category *))) == NULL)
		OBJC_ERROR("Not enough memory for category %s of class %s!\n",
		    category->categoryName, category->className);

	categories[0] = category;
	categories[1] = NULL;
	objc_hashtable_set(categoriesMap, category->className, categories);

	if (class != Nil && class->info & OBJC_CLASS_INFO_SETUP) {
		objc_update_dtable(class);
		objc_update_dtable(class->isa);
	}
}

void
objc_register_all_categories(struct objc_abi_symtab *symtab)
objc_register_all_categories(struct objc_symtab *symtab)
{
	struct objc_abi_category **categories =
	    (struct objc_abi_category **)symtab->defs + symtab->classDefsCount;
	struct objc_category **categories =
	    (struct objc_category **)symtab->defs + symtab->classDefsCount;

	for (size_t i = 0; i < symtab->categoryDefsCount; i++) {
		registerSelectors(categories[i]);
		registerCategory(categories[i]);
	}
}

Modified src/runtime/class.m from [d1f09c48dd] to [f4d6489e81].

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
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







-
+





-
+




-
-
+
+

-
+







static Class *loadQueue = NULL;
static size_t loadQueueCount = 0;
static struct objc_dtable *emptyDTable = NULL;
static unsigned lookupsUntilFastPath = 128;
static struct objc_sparsearray *fastPath = NULL;

static void
registerClass(struct objc_abi_class *rawClass)
registerClass(Class class)
{
	if (classes == NULL)
		classes = objc_hashtable_new(
		    objc_hash_string, objc_equal_string, 2);

	objc_hashtable_set(classes, rawClass->name, rawClass);
	objc_hashtable_set(classes, class->name, class);

	if (emptyDTable == NULL)
		emptyDTable = objc_dtable_new();

	rawClass->DTable = emptyDTable;
	rawClass->metaclass->DTable = emptyDTable;
	class->DTable = emptyDTable;
	class->isa->DTable = emptyDTable;

	if (strcmp(rawClass->name, "Protocol") != 0)
	if (strcmp(class->name, "Protocol") != 0)
		classesCount++;
}

bool
class_registerAlias_np(Class class, const char *name)
{
	objc_global_mutex_lock();
67
68
69
70
71
72
73
74

75
76


77
78

79
80
81


82
83
84
85
86
87
88
89
67
68
69
70
71
72
73

74
75

76
77
78

79



80
81

82
83
84
85
86
87
88







-
+

-
+
+

-
+
-
-
-
+
+
-








	objc_global_mutex_unlock();

	return YES;
}

static void
registerSelectors(struct objc_abi_class *rawClass)
registerSelectors(Class class)
{
	struct objc_abi_method_list *methodList;
	struct objc_method_list *iter;
	unsigned int i;

	for (methodList = rawClass->methodList; methodList != NULL;
	for (iter = class->methodList; iter != NULL; iter = iter->next)
	    methodList = methodList->next)
		for (unsigned int i = 0; i < methodList->count; i++)
			objc_register_selector((struct objc_abi_selector *)
		for (i = 0; i < iter->count; i++)
			objc_register_selector(&iter->methods[i].selector);
			    &methodList->methods[i]);
}

Class
objc_classname_to_class(const char *name, bool cache)
{
	Class class;

288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301







-
+







setupClass(Class class)
{
	const char *superclassName;

	if (class->info & OBJC_CLASS_INFO_SETUP)
		return;

	superclassName = ((struct objc_abi_class *)class)->superclass;
	superclassName = (const char *)class->superclass;
	if (superclassName != NULL) {
		Class super = objc_classname_to_class(superclassName, false);

		if (super == Nil)
			return;

		setupClass(super);
413
414
415
416
417
418
419
420

421
422
423
424

425
426
427
428



429
430
431
432
433
434
435
412
413
414
415
416
417
418

419
420
421


422
423



424
425
426
427
428
429
430
431
432
433







-
+


-
-
+

-
-
-
+
+
+







			if (loadQueue == NULL)
				OBJC_ERROR("Not enough memory for load queue!");
		}
	}
}

void
objc_register_all_classes(struct objc_abi_symtab *symtab)
objc_register_all_classes(struct objc_symtab *symtab)
{
	for (uint16_t i = 0; i < symtab->classDefsCount; i++) {
		struct objc_abi_class *rawClass =
		    (struct objc_abi_class *)symtab->defs[i];
		Class class = (Class)symtab->defs[i];

		registerClass(rawClass);
		registerSelectors(rawClass);
		registerSelectors(rawClass->metaclass);
		registerClass(class);
		registerSelectors(class);
		registerSelectors(class->isa);
	}

	for (uint16_t i = 0; i < symtab->classDefsCount; i++) {
		Class class = (Class)symtab->defs[i];

		if (hasLoad(class)) {
			setupClass(class);
488
489
490
491
492
493
494
495

496
497
498
499
500
501
502
486
487
488
489
490
491
492

493
494
495
496
497
498
499
500







-
+







}

void
objc_registerClassPair(Class class)
{
	objc_global_mutex_lock();

	registerClass((struct objc_abi_class *)class);
	registerClass(class);

	if (class->superclass != Nil) {
		addSubclass(class);
		addSubclass(class->isa);
	}

	class->info |= OBJC_CLASS_INFO_SETUP;
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
859
860
861
862
863
864
865


866
867
868
869
870
871
872







-
-







{
	return class_getName(object_getClass(object));
}

static void
unregisterClass(Class class)
{
	struct objc_abi_class *rawClass = (struct objc_abi_class *)class;

	if ((class->info & OBJC_CLASS_INFO_SETUP) && class->superclass != Nil &&
	    class->superclass->subclassList != NULL) {
		size_t i = SIZE_MAX, count = 0;
		Class *tmp;

		for (tmp = class->superclass->subclassList;
		    *tmp != Nil; tmp++) {
898
899
900
901
902
903
904
905

906
907
908
909
910
911
912
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908







-
+








	if (class->DTable != NULL && class->DTable != emptyDTable)
		objc_dtable_free(class->DTable);

	class->DTable = NULL;

	if ((class->info & OBJC_CLASS_INFO_SETUP) && class->superclass != Nil)
		rawClass->superclass = class->superclass->name;
		class->superclass = (Class)class->superclass->name;

	class->info &= ~OBJC_CLASS_INFO_SETUP;
}

void
objc_unregister_class(Class class)
{

Modified src/runtime/init.m from [8f157610ad] to [b72034f7da].

17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
17
18
19
20
21
22
23

24
25


26
27
28
29
30
31
32







-
+

-
-








#include "config.h"

#import "ObjFWRT.h"
#import "private.h"

void
__objc_exec_class(void *module_)
__objc_exec_class(struct objc_module *module)
{
	struct objc_abi_module *module = module_;

	objc_global_mutex_lock();

	objc_register_all_selectors(module->symtab);
	objc_register_all_classes(module->symtab);
	objc_register_all_categories(module->symtab);
	objc_init_static_instances(module->symtab);

Modified src/runtime/linklib/linklib.m from [97d16c1155] to [701acb1f6d].

136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150







-
+







DESTRUCTOR_P(ObjFWRT, 4000)
{
	dtor();
}
#endif

void
__objc_exec_class(void *module)
__objc_exec_class(struct objc_module *module)
{
	/*
	 * The compiler generates constructors that call into this, so it is
	 * possible that we are not set up yet when we get called.
	 */
	ctor();

Modified src/runtime/morphos-clib.h from [d7678b7243] to [4d1d4f1cae].

1
2
3
4

5
6
7
8
9
10
11
1
2
3

4
5
6
7
8
9
10
11



-
+







/* Functions that are only for the linklib. */
bool glue_objc_init(unsigned int, struct objc_libc *, FILE *, FILE *);
/* All other functions. */
void glue___objc_exec_class(void *);
void glue___objc_exec_class(struct objc_module *);
IMP glue_objc_msg_lookup(id, SEL);
IMP glue_objc_msg_lookup_stret(id, SEL);
IMP glue_objc_msg_lookup_super(struct objc_super *, SEL);
IMP glue_objc_msg_lookup_super_stret(struct objc_super *, SEL);
Class glue_objc_lookUpClass(const char *);
Class glue_objc_getClass(const char *);
Class glue_objc_getRequiredClass(const char *);

Modified src/runtime/private.h from [182926c01c] to [dd3eb1cd1b].

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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-











-
-
-
-
-
-
-
-
-
+




-
+

-
+





-
+



-
+







#  define _Nonnull
# endif
# ifndef _Nullable
#  define _Nullable
# endif
#endif

struct objc_abi_class {
	struct objc_abi_class *_Nonnull metaclass;
	const char *_Nullable superclass;
	const char *_Nonnull name;
	unsigned long version;
	unsigned long info;
	long instanceSize;
	void *_Nullable ivars;
	struct objc_abi_method_list *_Nullable methodList;
	void *_Nullable DTable;
	void *_Nullable subclassList;
	void *_Nullable siblingClass;
	void *_Nullable protocols;
	void *_Nullable GCObjectType;
	long ABIVersion;
	int32_t *_Nonnull *_Nullable ivarOffsets;
	void *_Nullable properties;
};

struct objc_abi_selector {
	const char *_Nonnull name;
	const char *_Nullable typeEncoding;
};

struct objc_abi_method {
	struct objc_abi_selector selector;
	IMP _Nonnull implementation;
};

struct objc_abi_method_list {
	struct objc_abi_method_list *_Nullable next;
	unsigned int count;
	struct objc_abi_method methods[1];
};

struct objc_ivar {
	const char *_Nonnull name;
	const char *_Nonnull typeEncoding;
	unsigned int offset;
};

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

struct objc_abi_category {
	const char *_Nonnull categoryName;
	const char *_Nonnull className;
	struct objc_abi_method_list *_Nullable instanceMethods;
	struct objc_abi_method_list *_Nullable classMethods;
	struct objc_protocol_list *_Nullable protocols;
};

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

struct objc_abi_symtab {
struct objc_symtab {
	unsigned long unknown;
	struct objc_abi_selector *_Nullable selectorRefs;
	struct objc_selector *_Nullable selectorRefs;
	uint16_t classDefsCount;
	uint16_t categoryDefsCount;
	void *_Nonnull defs[1];
};

struct objc_abi_module {
struct objc_module {
	unsigned long version;	/* 9 = non-fragile */
	unsigned long size;
	const char *_Nullable name;
	struct objc_abi_symtab *_Nonnull symtab;
	struct objc_symtab *_Nonnull symtab;
};

struct objc_hashtable_bucket {
	const void *_Nonnull key, *_Nonnull object;
	uint32_t hash;
};

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
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







-
+





-
+
















-
-
+
+














-
+







	type name = reg_##name;
# endif
# undef stdout
# undef stderr
extern FILE *stdout, *stderr;
#endif

extern void objc_register_all_categories(struct objc_abi_symtab *_Nonnull);
extern void objc_register_all_categories(struct objc_symtab *_Nonnull);
extern struct objc_category *_Nullable *_Nullable
    objc_categories_for_class(Class _Nonnull);
extern void objc_unregister_all_categories(void);
extern void objc_initialize_class(Class _Nonnull);
extern void objc_update_dtable(Class _Nonnull);
extern void objc_register_all_classes(struct objc_abi_symtab *_Nonnull);
extern void objc_register_all_classes(struct objc_symtab *_Nonnull);
extern Class _Nullable objc_classname_to_class(const char *_Nonnull, bool);
extern void objc_unregister_class(Class _Nonnull);
extern void objc_unregister_all_classes(void);
extern uint32_t objc_hash_string(const void *_Nonnull);
extern bool objc_equal_string(const void *_Nonnull, const void *_Nonnull);
extern struct objc_hashtable *_Nonnull objc_hashtable_new(
    uint32_t (*_Nonnull)(const void *_Nonnull),
    bool (*_Nonnull)(const void *_Nonnull, const void *_Nonnull), uint32_t);
extern struct objc_hashtable_bucket objc_deleted_bucket;
extern void objc_hashtable_set(struct objc_hashtable *_Nonnull,
    const void *_Nonnull, const void *_Nonnull);
extern void *_Nullable objc_hashtable_get(struct objc_hashtable *_Nonnull,
    const void *_Nonnull);
extern void objc_hashtable_delete(struct objc_hashtable *_Nonnull,
    const void *_Nonnull);
extern void objc_hashtable_free(struct objc_hashtable *_Nonnull);
extern void objc_register_selector(struct objc_abi_selector *_Nonnull);
extern void objc_register_all_selectors(struct objc_abi_symtab *_Nonnull);
extern void objc_register_selector(struct objc_selector *_Nonnull);
extern void objc_register_all_selectors(struct objc_symtab *_Nonnull);
extern void objc_unregister_all_selectors(void);
extern struct objc_sparsearray *_Nonnull objc_sparsearray_new(uint8_t);
extern void *_Nullable objc_sparsearray_get(struct objc_sparsearray *_Nonnull,
    uintptr_t);
extern void objc_sparsearray_set(struct objc_sparsearray *_Nonnull, uintptr_t,
    void *_Nullable);
extern void objc_sparsearray_free(struct objc_sparsearray *_Nonnull);
extern struct objc_dtable *_Nonnull objc_dtable_new(void);
extern void objc_dtable_copy(struct objc_dtable *_Nonnull,
    struct objc_dtable *_Nonnull);
extern void objc_dtable_set(struct objc_dtable *_Nonnull, uint32_t,
    IMP _Nullable);
extern void objc_dtable_free(struct objc_dtable *_Nonnull);
extern void objc_dtable_cleanup(void);
extern void objc_init_static_instances(struct objc_abi_symtab *_Nonnull);
extern void objc_init_static_instances(struct objc_symtab *_Nonnull);
extern void objc_forget_pending_static_instances(void);
#ifdef OF_HAVE_THREADS
extern void objc_global_mutex_lock(void);
extern void objc_global_mutex_unlock(void);
extern void objc_global_mutex_free(void);
#else
# define objc_global_mutex_lock()

Modified src/runtime/selector.m from [99b2d0f965] to [b2795ffb4b].

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
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







-
+

-
+








-
-
-
+
+
+






-
+
-










-
+




-
+

-
+


-
+


-
+


-
+





-
-
+
+

-
+


-
+



-
+

-
+




-
+
-
-
+







static struct objc_hashtable *selectors = NULL;
static uint32_t selectorsCount = 0;
static struct objc_sparsearray *selectorNames = NULL;
static void **freeList = NULL;
static size_t freeListCount = 0;

void
objc_register_selector(struct objc_abi_selector *rawSelector)
objc_register_selector(struct objc_selector *selector)
{
	struct objc_selector *selector;
	SEL existingSelector;
	const char *name;

	if (selectorsCount > SEL_MAX)
		OBJC_ERROR("Out of selector slots!");

	if (selectors == NULL)
		selectors = objc_hashtable_new(
		    objc_hash_string, objc_equal_string, 2);
	else if ((selector = objc_hashtable_get(selectors,
	    rawSelector->name)) != NULL) {
		((struct objc_selector *)rawSelector)->UID = selector->UID;
	else if ((existingSelector = objc_hashtable_get(selectors,
	    (const char *)selector->UID)) != NULL) {
		selector->UID = existingSelector->UID;
		return;
	}

	if (selectorNames == NULL)
		selectorNames = objc_sparsearray_new(SEL_SIZE);

	name = rawSelector->name;
	name = (const char *)selector->UID;
	selector = (struct objc_selector *)rawSelector;
	selector->UID = selectorsCount++;

	objc_hashtable_set(selectors, name, selector);
	objc_sparsearray_set(selectorNames, (uint32_t)selector->UID,
	    (void *)name);
}

SEL
sel_registerName(const char *name)
{
	struct objc_abi_selector *rawSelector;
	struct objc_selector *selector;

	objc_global_mutex_lock();

	if (selectors != NULL &&
	    (rawSelector= objc_hashtable_get(selectors, name)) != NULL) {
	    (selector = objc_hashtable_get(selectors, name)) != NULL) {
		objc_global_mutex_unlock();
		return (SEL)rawSelector;
		return (SEL)selector;
	}

	if ((rawSelector = malloc(sizeof(*rawSelector))) == NULL)
	if ((selector = malloc(sizeof(*selector))) == NULL)
		OBJC_ERROR("Not enough memory to allocate selector!");

	if ((rawSelector->name = of_strdup(name)) == NULL)
	if ((selector->UID = (uintptr_t)of_strdup(name)) == 0)
		OBJC_ERROR("Not enough memory to allocate selector!");

	rawSelector->typeEncoding = NULL;
	selector->typeEncoding = NULL;

	if ((freeList = realloc(freeList,
	    sizeof(void *) * (freeListCount + 2))) == NULL)
		OBJC_ERROR("Not enough memory to allocate selector!");

	freeList[freeListCount++] = rawSelector;
	freeList[freeListCount++] = (char *)rawSelector->name;
	freeList[freeListCount++] = selector;
	freeList[freeListCount++] = (char *)selector->UID;

	objc_register_selector(rawSelector);
	objc_register_selector(selector);

	objc_global_mutex_unlock();
	return (SEL)rawSelector;
	return (SEL)selector;
}

void
objc_register_all_selectors(struct objc_abi_symtab *symtab)
objc_register_all_selectors(struct objc_symtab *symtab)
{
	struct objc_abi_selector *rawSelector;
	struct objc_selector *selector;

	if (symtab->selectorRefs == NULL)
		return;

	for (rawSelector = symtab->selectorRefs; rawSelector->name != NULL;
	for (selector = symtab->selectorRefs; selector->UID != 0; selector++)
	    rawSelector++)
		objc_register_selector(rawSelector);
		objc_register_selector(selector);
}

const char *
sel_getName(SEL selector)
{
	const char *ret;

Modified src/runtime/static-instances.m from [8c2bdd3f07] to [331920028d].

19
20
21
22
23
24
25
26

27
28
29
30

31
32

33
34
35
36
37
38
39
19
20
21
22
23
24
25

26
27
28
29

30
31

32
33
34
35
36
37
38
39







-
+



-
+

-
+








#include <stdio.h>
#include <stdlib.h>

#import "ObjFWRT.h"
#import "private.h"

static struct objc_abi_static_instances **staticInstancesList = NULL;
static struct objc_static_instances **staticInstancesList = NULL;
static size_t staticInstancesCount = 0;

void
objc_init_static_instances(struct objc_abi_symtab *symtab)
objc_init_static_instances(struct objc_symtab *symtab)
{
	struct objc_abi_static_instances **staticInstances;
	struct objc_static_instances **staticInstances;

	/* Check if the class for a static instance became available */
	for (size_t i = 0; i < staticInstancesCount; i++) {
		Class class = objc_lookUpClass(
		    staticInstancesList[i]->className);

		if (class != Nil) {
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
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







-
+














-
+














-
+







				break;
			}

			staticInstancesList[i] =
			    staticInstancesList[staticInstancesCount];

			staticInstancesList = realloc(staticInstancesList,
			    sizeof(struct objc_abi_static_instances *) *
			    sizeof(*staticInstancesList) *
			    staticInstancesCount);

			if (staticInstancesList == NULL)
				OBJC_ERROR("Not enough memory for list of "
				    "static instances!");

			/*
			 * We moved the last entry to the current index,
			 * therefore we need to run again for the current index.
			 */
			i--;
		}
	}

	staticInstances = (struct objc_abi_static_instances **)
	staticInstances = (struct objc_static_instances **)
	    symtab->defs[symtab->classDefsCount + symtab->categoryDefsCount];

	if (staticInstances == NULL)
		return;

	for (; *staticInstances != NULL; staticInstances++) {
		Class class = objc_lookUpClass((*staticInstances)->className);

		if (class != Nil) {
			for (id *instances = (*staticInstances)->instances;
			    *instances != nil; instances++)
				object_setClass(*instances, class);
		} else {
			staticInstancesList = realloc(staticInstancesList,
			    sizeof(struct objc_abi_static_instances *) *
			    sizeof(*staticInstancesList) *
			    (staticInstancesCount + 1));

			if (staticInstancesList == NULL)
				OBJC_ERROR("Not enough memory for list of "
				    "static instances!");

			staticInstancesList[staticInstancesCount++] =

Modified tests/OFBlockTests.m from [6e73d74cf4] to [a74daa9112].

17
18
19
20
21
22
23
24
25
26



27
28
29
30
31
32
33
17
18
19
20
21
22
23



24
25
26
27
28
29
30
31
32
33







-
-
-
+
+
+








#include "config.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFBlock";

extern struct objc_abi_class _NSConcreteStackBlock;
extern struct objc_abi_class _NSConcreteGlobalBlock;
extern struct objc_abi_class _NSConcreteMallocBlock;
extern struct objc_class _NSConcreteStackBlock;
extern struct objc_class _NSConcreteGlobalBlock;
extern struct objc_class _NSConcreteMallocBlock;

static void (^g)(void) = ^ {};

static int
(^returnStackBlock(void))(void)
{
	__block int i = 42;