]> git.saurik.com Git - apple/objc4.git/blob - test/unwind.m
objc4-756.2.tar.gz
[apple/objc4.git] / test / unwind.m
1 // TEST_CONFIG
2
3 #include "test.h"
4 #include <objc/objc-exception.h>
5 #include <Foundation/NSObject.h>
6
7 static int state;
8
9 @interface Foo : NSObject @end
10 @interface Bar : NSObject @end
11
12 @interface Foo (Unimplemented)
13 +(void)method;
14 @end
15
16 @implementation Bar @end
17
18 @implementation Foo
19
20 -(void)check { state++; }
21 +(void)check { testassert(!"caught class object, not instance"); }
22
23 static id exc;
24
25 static void handler(id unused, void *ctx) __attribute__((used));
26 static void handler(id unused __unused, void *ctx __unused)
27 {
28 testassert(state == 3); state++;
29 }
30
31 +(BOOL) resolveClassMethod:(SEL)__unused name
32 {
33 testassert(state == 1); state++;
34 #if TARGET_OS_OSX
35 objc_addExceptionHandler(&handler, 0);
36 testassert(state == 2);
37 #else
38 state++; // handler would have done this
39 #endif
40 state++;
41 exc = [Foo new];
42 @throw exc;
43 }
44
45
46 @end
47
48 int main()
49 {
50 // unwind exception and alt handler through objc_msgSend()
51
52 PUSH_POOL {
53
54 const int count = is_guardmalloc() ? 1000 : 100000;
55 state = 0;
56 for (int i = 0; i < count; i++) {
57 @try {
58 testassert(state == 0); state++;
59 [Foo method];
60 testassert(0);
61 } @catch (Bar *e) {
62 testassert(0);
63 } @catch (Foo *e) {
64 testassert(e == exc);
65 testassert(state == 4); state++;
66 testassert(state == 5); [e check]; // state++
67 RELEASE_VAR(exc);
68 } @catch (id e) {
69 testassert(0);
70 } @catch (...) {
71 testassert(0);
72 } @finally {
73 testassert(state == 6); state++;
74 }
75 testassert(state == 7); state = 0;
76 }
77
78 } POP_POOL;
79
80 succeed(__FILE__);
81 }