1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/*
* Copyright (c) 2008-2021 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"
#import "TestsAppDelegate.h"
static OFString *module = @"OFBlock";
#if defined(OF_OBJFW_RUNTIME)
extern struct objc_class _NSConcreteStackBlock;
extern struct objc_class _NSConcreteGlobalBlock;
extern struct objc_class _NSConcreteMallocBlock;
#elif defined(OF_APPLE_RUNTIME)
extern void *_NSConcreteStackBlock;
extern void *_NSConcreteGlobalBlock;
extern void *_NSConcreteMallocBlock;
#endif
static void (^g)(void) = ^ {};
static int
(^returnStackBlock(void))(void)
{
__block int i = 42;
return [Block_copy(^ int { return ++i; }) autorelease];
}
static double
forwardTest(void)
{
__block double d;
void (^b)(void) = Block_copy(^ {
d = 5;
});
b();
Block_release(b);
return d;
}
@implementation TestsAppDelegate (OFBlockTests)
- (void)blockTests
{
void *pool = objc_autoreleasePoolPush();
__block int x;
void (^s)(void) = ^ { x = 0; };
void (^m)(void);
int (^v)(void);
TEST(@"Class of stack block",
(Class)&_NSConcreteStackBlock == objc_getClass("OFStackBlock") &&
[s isKindOfClass: [OFBlock class]])
#if !defined(OF_WINDOWS) || !defined(__clang__) || !defined(OF_NO_SHARED)
/*
* Causes a linker error on Windows with Clang when compiling as a
* static library. This is a bug in Clang.
*/
TEST(@"Class of global block",
(Class)&_NSConcreteGlobalBlock == objc_getClass("OFGlobalBlock") &&
[g isKindOfClass: [OFBlock class]])
#endif
TEST(@"Class of a malloc block",
(Class)&_NSConcreteMallocBlock == objc_getClass("OFMallocBlock"))
TEST(@"Copying a stack block",
(m = [[s copy] autorelease]) &&
[m class] == objc_getClass("OFMallocBlock") &&
[m isKindOfClass: [OFBlock class]])
TEST(@"Copying a stack block and referencing its variable",
forwardTest() == 5)
TEST(@"Copying a stack block and using its copied variable",
(v = returnStackBlock()) && v() == 43 && v() == 44 && v() == 45)
TEST(@"Copying a global block", (id)g == [[g copy] autorelease])
#ifndef __clang_analyzer__
TEST(@"Copying a malloc block",
(id)m == [m copy] && [m retainCount] == 2)
#endif
TEST(@"Autorelease a stack block", R([s autorelease]))
TEST(@"Autorelease a global block", R([g autorelease]))
#ifndef __clang_analyzer__
TEST(@"Autorelease a malloc block", R([m autorelease]))
#endif
objc_autoreleasePoolPop(pool);
}
@end
|
|
|
|
|
|
|
|
>
|
>
|
>
|
|
|
|
|
|
>
|
>
>
|
|
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
/*
* Copyright (c) 2008-2022 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"
#import "TestsAppDelegate.h"
static OFString *const module = @"OFBlock";
#if defined(OF_OBJFW_RUNTIME)
extern struct objc_class _NSConcreteStackBlock;
extern struct objc_class _NSConcreteGlobalBlock;
extern struct objc_class _NSConcreteMallocBlock;
#elif defined(OF_APPLE_RUNTIME)
extern void *_NSConcreteStackBlock;
extern void *_NSConcreteGlobalBlock;
extern void *_NSConcreteMallocBlock;
#endif
static void (^globalBlock)(void) = ^ {};
static int
(^returnStackBlock(void))(void)
{
__block int i = 42;
return [Block_copy(^ int { return ++i; }) autorelease];
}
static double
forwardTest(void)
{
__block double d;
void (^block)(void) = Block_copy(^ {
d = 5;
});
block();
Block_release(block);
return d;
}
@implementation TestsAppDelegate (OFBlockTests)
- (void)blockTests
{
void *pool = objc_autoreleasePoolPush();
__block int x;
void (^stackBlock)(void) = ^ {
x = 0;
(void)x;
};
void (^mallocBlock)(void);
int (^voidBlock)(void);
TEST(@"Class of stack block",
(Class)&_NSConcreteStackBlock == objc_getClass("OFStackBlock") &&
[stackBlock isKindOfClass: [OFBlock class]])
#if !defined(OF_WINDOWS) || !defined(__clang__) || !defined(OF_NO_SHARED)
/*
* Causes a linker error on Windows with Clang when compiling as a
* static library. This is a bug in Clang.
*/
TEST(@"Class of global block",
(Class)&_NSConcreteGlobalBlock == objc_getClass("OFGlobalBlock") &&
[globalBlock isKindOfClass: [OFBlock class]])
#endif
TEST(@"Class of a malloc block",
(Class)&_NSConcreteMallocBlock == objc_getClass("OFMallocBlock"))
TEST(@"Copying a stack block",
(mallocBlock = [[stackBlock copy] autorelease]) &&
[mallocBlock class] == objc_getClass("OFMallocBlock") &&
[mallocBlock isKindOfClass: [OFBlock class]])
TEST(@"Copying a stack block and referencing its variable",
forwardTest() == 5)
TEST(@"Copying a stack block and using its copied variable",
(voidBlock = returnStackBlock()) && voidBlock() == 43 &&
voidBlock() == 44 && voidBlock() == 45)
TEST(@"Copying a global block",
(id)globalBlock == [[globalBlock copy] autorelease])
#ifndef __clang_analyzer__
TEST(@"Copying a malloc block",
(id)mallocBlock == [mallocBlock copy] &&
[mallocBlock retainCount] == 2)
#endif
TEST(@"Autorelease a stack block", R([stackBlock autorelease]))
TEST(@"Autorelease a global block", R([globalBlock autorelease]))
#ifndef __clang_analyzer__
TEST(@"Autorelease a malloc block", R([mallocBlock autorelease]))
#endif
objc_autoreleasePoolPop(pool);
}
@end
|