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
3 // found in the LICENSE file.
5 #import "chrome/common/mac/objc_method_swizzle.h"
7 #import "base/logging.h"
9 namespace ObjcEvilDoers {
11 Method GetImplementedInstanceMethod(Class aClass, SEL aSelector) {
13 unsigned int methodCount = 0;
14 Method* methodList = class_copyMethodList(aClass, &methodCount);
16 for (unsigned int i = 0; i < methodCount; ++i) {
17 if (method_getName(methodList[i]) == aSelector) {
18 method = methodList[i];
27 IMP SwizzleImplementedInstanceMethods(
28 Class aClass, const SEL originalSelector, const SEL alternateSelector) {
29 // The methods must both be implemented by the target class, not
30 // inherited from a superclass.
31 Method original = GetImplementedInstanceMethod(aClass, originalSelector);
32 Method alternate = GetImplementedInstanceMethod(aClass, alternateSelector);
35 if (!original || !alternate) {
39 // The argument and return types must match exactly.
40 const char* originalTypes = method_getTypeEncoding(original);
41 const char* alternateTypes = method_getTypeEncoding(alternate);
42 DCHECK(originalTypes);
43 DCHECK(alternateTypes);
44 DCHECK(0 == strcmp(originalTypes, alternateTypes));
45 if (!originalTypes || !alternateTypes ||
46 strcmp(originalTypes, alternateTypes)) {
50 IMP ret = method_getImplementation(original);
52 method_exchangeImplementations(original, alternate);
57 } // namespace ObjcEvilDoers