ObjFW  Diff

Differences From Artifact [0477c3fb09]:

To Artifact [e705635cfb]:


1
2

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
1

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

-
+




















-
-



















+







/*
 * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im>
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "unistd_wrapper.h"

#include <assert.h>

#ifdef OF_APPLE_RUNTIME
# include <dlfcn.h>
#endif

#ifdef HAVE_GETRANDOM
# include <sys/random.h>
#endif

#import "OFObject.h"
#import "OFArray.h"
#ifdef OF_HAVE_ATOMIC_OPS
# import "OFAtomic.h"
#endif
#import "OFLocale.h"
#import "OFMethodSignature.h"
#import "OFRunLoop.h"
#if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS)
# import "OFPlainMutex.h"	/* For OFSpinlock */
#endif
#import "OFStdIOStream.h"
#import "OFString.h"
#import "OFThread.h"
#import "OFTimer.h"
#import "OFValue.h"

#import "OFAllocFailedException.h"
#import "OFEnumerationMutationException.h"
61
62
63
64
65
66
67

68

69
70
71
72
73
74
75
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76







+

+







#endif

#ifdef OF_WINDOWS
# include <windows.h>
#endif

#ifdef OF_AMIGAOS
# define Class IntuitionClass
# include <proto/exec.h>
# undef Class
#endif

#ifdef OF_APPLE_RUNTIME
extern id _Nullable _objc_rootAutorelease(id _Nullable object);
#endif
#if defined(OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR)
extern id OFForward(id, SEL, ...);
248
249
250
251
252
253
254
255
256
257
258
259
260
261


262
263
264
265
266
267
268
269
270
271
272
273
274
275

276

277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
249
250
251
252
253
254
255

256
257
258
259


260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293

294
295
296


297
298
299
300
301
302
303







-




-
-
+
+














+
-
+









-
+






-
+


-
-







	return method_getTypeEncoding(method);
}

#if !defined(OF_APPLE_RUNTIME) || defined(__OBJC2__)
static void
uncaughtExceptionHandler(id exception)
{
	OFString *description = [exception description];
	OFArray OF_GENERIC(OFValue *) *stackTraceAddresses = nil;
	OFArray OF_GENERIC(OFString *) *stackTraceSymbols = nil;
	OFStringEncoding encoding = [OFLocale encoding];

	fprintf(stderr, "\nRuntime error: Unhandled exception:\n%s\n",
	    [description cStringWithEncoding: encoding]);
	OFLog(@"Runtime error: Unhandled exception:");
	OFLog(@"%@", exception);

	if ([exception respondsToSelector: @selector(stackTraceAddresses)])
		stackTraceAddresses = [exception stackTraceAddresses];

	if (stackTraceAddresses != nil) {
		size_t count = stackTraceAddresses.count;

		if ([exception respondsToSelector:
		    @selector(stackTraceSymbols)])
			stackTraceSymbols = [exception stackTraceSymbols];

		if (stackTraceSymbols.count != count)
			stackTraceSymbols = nil;

		OFLog(@"");
		fputs("\nStack trace:\n", stderr);
		OFLog(@"Stack trace:");

		if (stackTraceSymbols != nil) {
			for (size_t i = 0; i < count; i++) {
				void *address = [[stackTraceAddresses
				    objectAtIndex: i] pointerValue];
				const char *symbol = [[stackTraceSymbols
				    objectAtIndex: i]
				    cStringWithEncoding: encoding];

				fprintf(stderr, "  %p  %s\n", address, symbol);
				OFLog(@"  %p  %s", address, symbol);
			}
		} else {
			for (size_t i = 0; i < count; i++) {
				void *address = [[stackTraceAddresses
				    objectAtIndex: i] pointerValue];

				fprintf(stderr, "  %p\n", address);
				OFLog(@"  %p", address);
			}
		}

		fputs("\n", stderr);
	}

	abort();
}
#endif

static void
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
383
384
385
386
387
388
389

390
391
392
393
394
395
396







-







}

/* References for static linking */
void
_references_to_categories_of_OFObject(void)
{
	_OFObject_KeyValueCoding_reference = 1;
	_OFObject_Serialization_reference = 1;
}

@implementation OFObject
+ (void)load
{
#if !defined(OF_APPLE_RUNTIME) || defined(__OBJC2__)
	objc_setUncaughtExceptionHandler(uncaughtExceptionHandler);
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
434
435
436
437
438
439
440





441
442
443
444
445
446
447







-
-
-
-
-







}

+ (instancetype)alloc
{
	return OFAllocObject(self, 0, 0, NULL);
}

+ (instancetype)new
{
	return [[self alloc] init];
}

+ (Class)class
{
	return self;
}

+ (OFString *)className
{
473
474
475
476
477
478
479
480
481

482
483

484
485
486
487
488
489
490
466
467
468
469
470
471
472


473


474
475
476
477
478
479
480
481







-
-
+
-
-
+







+ (bool)instancesRespondToSelector: (SEL)selector
{
	return class_respondsToSelector(self, selector);
}

+ (bool)conformsToProtocol: (Protocol *)protocol
{
	Class c;

	for (Class iter = self; iter != Nil; iter = class_getSuperclass(iter))
	for (c = self; c != Nil; c = class_getSuperclass(c))
		if (class_conformsToProtocol(c, protocol))
		if (class_conformsToProtocol(iter, protocol))
			return true;

	return false;
}

+ (IMP)instanceMethodForSelector: (SEL)selector
{
578
579
580
581
582
583
584
585

586
587
588
589
590

591
592
593
594
595
596
597
569
570
571
572
573
574
575

576
577
578
579
580

581
582
583
584
585
586
587
588







-
+




-
+







	}

	[self inheritMethodsFromClass: superclass];
}

+ (bool)resolveClassMethod: (SEL)selector
{
	return NO;
	return false;
}

+ (bool)resolveInstanceMethod: (SEL)selector
{
	return NO;
	return false;
}

- (instancetype)init
{
	return self;
}

1167
1168
1169
1170
1171
1172
1173
1174

1175
1176
1177
1178
1179
1180
1181
1158
1159
1160
1161
1162
1163
1164

1165
1166
1167
1168
1169
1170
1171
1172







-
+







#endif

	return self;
}

- (unsigned int)retainCount
{
	assert(PRE_IVARS->retainCount >= 0);
	OFAssert(PRE_IVARS->retainCount >= 0);
	return PRE_IVARS->retainCount;
}

- (void)release
{
#if defined(OF_HAVE_ATOMIC_OPS)
	OFReleaseMemoryBarrier();