Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(725)

Side by Side Diff: chrome/common/mac/objc_zombie_unittest.mm

Issue 10913151: Remove runtime lookup of objc_setAssociatedObject (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address review comments Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import <Cocoa/Cocoa.h> 5 #import <Cocoa/Cocoa.h>
6 #include <dlfcn.h> 6 #include <dlfcn.h>
7 #include <objc/runtime.h>
7 8
8 #include "base/logging.h" 9 #include "base/logging.h"
9 #import "base/memory/scoped_nsobject.h" 10 #import "base/memory/scoped_nsobject.h"
10 #import "chrome/common/mac/objc_zombie.h" 11 #import "chrome/common/mac/objc_zombie.h"
11 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
12 #include "testing/platform_test.h" 13 #include "testing/platform_test.h"
13 14
14 namespace {
15
16 // Dynamically look up |objc_setAssociatedObject()|, which isn't
17 // available until the 10.6 SDK.
18
19 typedef void objc_setAssociatedObjectFn(id object, void *key, id value,
20 int policy);
21 objc_setAssociatedObjectFn* LookupSetAssociatedObjectFn() {
22 return reinterpret_cast<objc_setAssociatedObjectFn*>(
23 dlsym(RTLD_DEFAULT, "objc_setAssociatedObject"));
24 }
25
26 } // namespace
27
28 @interface ZombieCxxDestructTest : NSObject 15 @interface ZombieCxxDestructTest : NSObject
29 { 16 {
30 scoped_nsobject<id> aRef_; 17 scoped_nsobject<id> aRef_;
31 } 18 }
32 - (id)initWith:(id)anObject; 19 - (id)initWith:(id)anObject;
33 @end 20 @end
34 21
35 @implementation ZombieCxxDestructTest 22 @implementation ZombieCxxDestructTest
36 - (id)initWith:(id)anObject { 23 - (id)initWith:(id)anObject {
37 self = [super init]; 24 self = [super init];
38 if (self) { 25 if (self) {
39 aRef_.reset([anObject retain]); 26 aRef_.reset([anObject retain]);
40 } 27 }
41 return self; 28 return self;
42 } 29 }
43 @end 30 @end
44 31
45 @interface ZombieAssociatedObjectTest : NSObject 32 @interface ZombieAssociatedObjectTest : NSObject
46 + (BOOL)supportsAssociatedObjects;
47 - (id)initWithAssociatedObject:(id)anObject; 33 - (id)initWithAssociatedObject:(id)anObject;
48 @end 34 @end
49 35
50 @implementation ZombieAssociatedObjectTest 36 @implementation ZombieAssociatedObjectTest
51 37
52 + (BOOL)supportsAssociatedObjects {
53 if (LookupSetAssociatedObjectFn())
54 return YES;
55 return NO;
56 }
57
58 - (id)initWithAssociatedObject:(id)anObject { 38 - (id)initWithAssociatedObject:(id)anObject {
59 self = [super init]; 39 if ((self = [super init])) {
60 if (self) { 40 // The address of the variable itself is the unique key, the
61 objc_setAssociatedObjectFn* fn = LookupSetAssociatedObjectFn(); 41 // contents don't matter.
62 if (fn) { 42 static char kAssociatedObjectKey = 'x';
63 // Cribbed from 10.6 <objc/runtime.h>. 43 objc_setAssociatedObject(
64 static const int kObjcAssociationRetain = 01401; 44 self, &kAssociatedObjectKey, anObject, OBJC_ASSOCIATION_RETAIN);
65
66 // The address of the variable itself is the unique key, the
67 // contents don't matter.
68 static char kAssociatedObjectKey = 'x';
69
70 (*fn)(self, &kAssociatedObjectKey, anObject, kObjcAssociationRetain);
71 }
72 } 45 }
73 return self; 46 return self;
74 } 47 }
75 48
76 @end 49 @end
77 50
78 namespace { 51 namespace {
79 52
80 // Verify that the C++ destructors run when the last reference to the 53 // Verify that the C++ destructors run when the last reference to the
81 // object is released. 54 // object is released.
(...skipping 14 matching lines...) Expand all
96 soonInfected.reset(); 69 soonInfected.reset();
97 EXPECT_EQ(1u, [anObject retainCount]); 70 EXPECT_EQ(1u, [anObject retainCount]);
98 71
99 // The local reference should remain (C++ destructors aren't re-run). 72 // The local reference should remain (C++ destructors aren't re-run).
100 ObjcEvilDoers::ZombieDisable(); 73 ObjcEvilDoers::ZombieDisable();
101 EXPECT_EQ(1u, [anObject retainCount]); 74 EXPECT_EQ(1u, [anObject retainCount]);
102 } 75 }
103 76
104 // Verify that the associated objects are released when the object is 77 // Verify that the associated objects are released when the object is
105 // released. 78 // released.
106 // NOTE(shess): To test the negative, hardcode |g_objectDestruct| to
107 // the 10.5 version in |ZombieInit()|, and run this test on 10.6.
108 TEST(ObjcZombieTest, AssociatedObjectsReleased) { 79 TEST(ObjcZombieTest, AssociatedObjectsReleased) {
109 if (![ZombieAssociatedObjectTest supportsAssociatedObjects]) {
110 DLOG(ERROR)
111 << "ObjcZombieTest.AssociatedObjectsReleased not supported on 10.5";
112 return;
113 }
114
115 scoped_nsobject<id> anObject([[NSObject alloc] init]); 80 scoped_nsobject<id> anObject([[NSObject alloc] init]);
116 EXPECT_EQ(1u, [anObject retainCount]); 81 EXPECT_EQ(1u, [anObject retainCount]);
117 82
118 ASSERT_TRUE(ObjcEvilDoers::ZombieEnable(YES, 100)); 83 ASSERT_TRUE(ObjcEvilDoers::ZombieEnable(YES, 100));
119 84
120 scoped_nsobject<ZombieAssociatedObjectTest> soonInfected( 85 scoped_nsobject<ZombieAssociatedObjectTest> soonInfected(
121 [[ZombieAssociatedObjectTest alloc] initWithAssociatedObject:anObject]); 86 [[ZombieAssociatedObjectTest alloc] initWithAssociatedObject:anObject]);
122 EXPECT_EQ(2u, [anObject retainCount]); 87 EXPECT_EQ(2u, [anObject retainCount]);
123 88
124 // When |soonInfected| becomes a zombie, the associated object 89 // When |soonInfected| becomes a zombie, the associated object
125 // should be released. 90 // should be released.
126 soonInfected.reset(); 91 soonInfected.reset();
127 EXPECT_EQ(1u, [anObject retainCount]); 92 EXPECT_EQ(1u, [anObject retainCount]);
128 93
129 // The local reference should remain (associated objects not re-released). 94 // The local reference should remain (associated objects not re-released).
130 ObjcEvilDoers::ZombieDisable(); 95 ObjcEvilDoers::ZombieDisable();
131 EXPECT_EQ(1u, [anObject retainCount]); 96 EXPECT_EQ(1u, [anObject retainCount]);
132 } 97 }
133 98
134 } // namespace 99 } // namespace
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698