]> git.saurik.com Git - apple/objc4.git/blob - test/unwind.m
objc4-532.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 #if !defined(__OBJC2__)
8
9 int main()
10 {
11 succeed(__FILE__);
12 }
13
14 #else
15
16 static int state;
17
18 @interface Foo : NSObject @end
19 @interface Bar : NSObject @end
20
21 @interface Foo (Unimplemented)
22 +(void)method;
23 @end
24
25 @implementation Bar @end
26
27 @implementation Foo
28
29 -(void)check { state++; }
30 +(void)check { testassert(!"caught class object, not instance"); }
31
32 static id exc;
33
34 static void handler(id unused, void *ctx) __attribute__((used));
35 static void handler(id unused __unused, void *ctx __unused)
36 {
37 testassert(state == 3); state++;
38 }
39
40 +(BOOL) resolveClassMethod:(SEL)__unused name
41 {
42 testassert(state == 1); state++;
43 #if !TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
44 objc_addExceptionHandler(&handler, 0);
45 testassert(state == 2);
46 #else
47 state++; // handler would have done this
48 #endif
49 state++;
50 exc = [Foo new];
51 @throw exc;
52 }
53
54
55 @end
56
57 int main()
58 {
59 #if TARGET_IPHONE_SIMULATOR
60 testwarn("<rdar://problem/7965763> Simulator: cannot throw exceptions across objc_msgSend");
61 succeed(__FILE__);
62 #else
63 int i;
64
65 // unwind exception and alt handler through objc_msgSend()
66
67 PUSH_POOL {
68
69 state = 0;
70 for (i = 0; i < 100000; i++) {
71 @try {
72 testassert(state == 0); state++;
73 [Foo method];
74 testassert(0);
75 } @catch (Bar *e) {
76 testassert(0);
77 } @catch (Foo *e) {
78 testassert(e == exc);
79 testassert(state == 4); state++;
80 testassert(state == 5); [e check]; // state++
81 RELEASE_VAR(exc);
82 } @catch (id e) {
83 testassert(0);
84 } @catch (...) {
85 testassert(0);
86 } @finally {
87 testassert(state == 6); state++;
88 }
89 testassert(state == 7); state = 0;
90 }
91
92 } POP_POOL;
93
94 succeed(__FILE__);
95 #endif
96 }
97
98 #endif