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
@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
};

struct objc_abi_class _NSConcreteStackBlock = {
	&_NSConcreteStackBlock_metaclass, "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
};

struct objc_abi_class _NSConcreteGlobalBlock = {
	&_NSConcreteGlobalBlock_metaclass, "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
};

struct objc_abi_class _NSConcreteMallocBlock = {
	&_NSConcreteMallocBlock_metaclass, "OFBlock", "OFMallocBlock",
	8, OBJC_CLASS_INFO_CLASS, sizeof(of_block_literal_t), NULL, NULL

};

static struct {
	unsigned long unknown;
	struct objc_abi_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
};

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







|
|
|


|
|
|
>


|
|
|


|
|
|
>


|
|
|


|
|
|
>




|










|
|







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_class _NSConcreteStackBlock_metaclass = {
	(Class)(void *)"OFObject", (Class)(void *)"OFBlock", "OFStackBlock", 8,
	OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_class), 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_class _NSConcreteGlobalBlock_metaclass = {
	(Class)(void *)"OFObject", (Class)(void *)"OFBlock", "OFGlobalBlock", 8,
	OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_class), 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_class _NSConcreteMallocBlock_metaclass = {
	(Class)(void *)"OFObject", (Class)(void *)"OFBlock", "OFMallocBlock", 8,
	OBJC_CLASS_INFO_METACLASS, sizeof(struct objc_class), 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_selector *selectorRefs;
	uint16_t classDefsCount, categoryDefsCount;
	void *defs[4];
} symtab = {
	0, NULL, 3, 0,
	{
		&_NSConcreteStackBlock, &_NSConcreteGlobalBlock,
		&_NSConcreteMallocBlock, NULL
	}
};

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
# 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) void _Block_object_assign(void *, const void *,
    const int);
extern __declspec(dllexport) void _Block_object_dispose(const void *,
    const int);
# endif
#ifdef __cplusplus
}







|
|







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_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
#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;
#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);








|







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

/*
 * 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.
 */

extern void __objc_exec_class(void *_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);







>
|







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(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
	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)
{
	M68K_ARG(void *, module, a0)

	__objc_exec_class(module);
}

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







|

|







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(struct objc_module *module)
{
	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
==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)
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)









|







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

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

static struct objc_hashtable *categoriesMap = NULL;

static void
registerSelectors(struct objc_abi_category *category)
{
	for (struct objc_abi_method_list *methodList =


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

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

static void
registerCategory(struct objc_abi_category *category)
{
	struct objc_abi_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(
	    categoriesMap, category->className);

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

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

		if ((newCategories = realloc(categories,
		    (i + 2) * sizeof(struct objc_abi_category *))) == 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(
	    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)
{
	struct objc_abi_category **categories =
	    (struct objc_abi_category **)symtab->defs + symtab->classDefsCount;

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








|

|
>
>
|
<
|
|
<

|
<
|
|
<



|

|






|



|





|

















|
<














|

|
|







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_category *category)
{
	struct objc_method_list *iter;
	unsigned int i;

	for (iter = category->instanceMethods; iter != NULL; iter = iter->next)

		for (i = 0; i < iter->count; i++)
			objc_register_selector(&iter->methods[i].selector);


	for (iter = category->classMethods; iter != NULL; iter = iter->next)

		for (i = 0; i < iter->count; i++)
			objc_register_selector(&iter->methods[i].selector);

}

static void
registerCategory(struct objc_category *category)
{
	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_category **)objc_hashtable_get(
	    categoriesMap, category->className);

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

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

		if ((newCategories = realloc(categories,
		    (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(2 * sizeof(*categories))) == 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_symtab *symtab)
{
	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
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)
{
	if (classes == NULL)
		classes = objc_hashtable_new(
		    objc_hash_string, objc_equal_string, 2);

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

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

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

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

bool
class_registerAlias_np(Class class, const char *name)
{
	objc_global_mutex_lock();







|





|




|
|

|







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(Class class)
{
	if (classes == NULL)
		classes = objc_hashtable_new(
		    objc_hash_string, objc_equal_string, 2);

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

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

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

	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

	objc_global_mutex_unlock();

	return YES;
}

static void
registerSelectors(struct objc_abi_class *rawClass)
{
	struct objc_abi_method_list *methodList;


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

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








|

|
>

|
<
|
|
<







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(Class class)
{
	struct objc_method_list *iter;
	unsigned int i;

	for (iter = class->methodList; iter != NULL; iter = iter->next)

		for (i = 0; i < iter->count; i++)
			objc_register_selector(&iter->methods[i].selector);

}

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
setupClass(Class class)
{
	const char *superclassName;

	if (class->info & OBJC_CLASS_INFO_SETUP)
		return;

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

		if (super == Nil)
			return;

		setupClass(super);







|







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 = (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
			if (loadQueue == NULL)
				OBJC_ERROR("Not enough memory for load queue!");
		}
	}
}

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

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

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

		if (hasLoad(class)) {
			setupClass(class);







|


<
|

|
|
|







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_symtab *symtab)
{
	for (uint16_t i = 0; i < symtab->classDefsCount; i++) {

		Class class = (Class)symtab->defs[i];

		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
}

void
objc_registerClassPair(Class class)
{
	objc_global_mutex_lock();

	registerClass((struct objc_abi_class *)class);

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

	class->info |= OBJC_CLASS_INFO_SETUP;







|







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(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
{
	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++) {







<
<







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


	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

	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->info &= ~OBJC_CLASS_INFO_SETUP;
}

void
objc_unregister_class(Class class)
{







|







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

#include "config.h"

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

void
__objc_exec_class(void *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);








|

<
<







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(struct objc_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
DESTRUCTOR_P(ObjFWRT, 4000)
{
	dtor();
}
#endif

void
__objc_exec_class(void *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();








|







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(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
/* 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 *);
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 *);



|







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(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
#  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 {
	const char *_Nonnull className;
	id _Nullable instances[1];
};

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

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

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








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











<
<
<
<
<
<
<
<
|




|

|





|



|







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_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_static_instances {
	const char *_Nonnull className;
	id _Nullable instances[1];
};

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

struct objc_module {
	unsigned long version;	/* 9 = non-fragile */
	unsigned long size;
	const char *_Nullable name;
	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
	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 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 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_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_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()







|





|
















|
|














|







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_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_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_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_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
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)
{
	struct objc_selector *selector;
	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;
		return;
	}

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

	name = rawSelector->name;
	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;

	objc_global_mutex_lock();

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

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

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

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

	objc_register_selector(rawSelector);

	objc_global_mutex_unlock();
	return (SEL)rawSelector;
}

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

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

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

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








|

|








|
|
|






|
<










|




|

|


|


|


|





|
|

|


|



|

|




|
<
|







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_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 ((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 = (const char *)selector->UID;

	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_selector *selector;

	objc_global_mutex_lock();

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

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

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

	selector->typeEncoding = NULL;

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

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

	objc_register_selector(selector);

	objc_global_mutex_unlock();
	return (SEL)selector;
}

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

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

	for (selector = symtab->selectorRefs; selector->UID != 0; selector++)

		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

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

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

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

void
objc_init_static_instances(struct objc_abi_symtab *symtab)
{
	struct objc_abi_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) {







|



|

|







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_static_instances **staticInstancesList = NULL;
static size_t staticInstancesCount = 0;

void
objc_init_static_instances(struct objc_symtab *symtab)
{
	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
				break;
			}

			staticInstancesList[i] =
			    staticInstancesList[staticInstancesCount];

			staticInstancesList = realloc(staticInstancesList,
			    sizeof(struct objc_abi_static_instances *) *
			    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 **)
	    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 *) *
			    (staticInstancesCount + 1));

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

			staticInstancesList[staticInstancesCount++] =







|














|














|







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(*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_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(*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

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

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

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







|
|
|







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