From 65e3dc736c7958fb0a4eb3e8930229efa2d13089 Mon Sep 17 00:00:00 2001 From: theraven Date: Sat, 12 Jan 2013 15:49:39 +0000 Subject: [PATCH] Added test of forwarding mechanisms. --- Test/CMakeLists.txt | 1 + Test/Forward.m | 73 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 Test/Forward.m diff --git a/Test/CMakeLists.txt b/Test/CMakeLists.txt index 643dcc5..a8cb573 100644 --- a/Test/CMakeLists.txt +++ b/Test/CMakeLists.txt @@ -9,6 +9,7 @@ set(TESTS BoxedForeignException.m ExceptionTest.m ForeignException.m + Forward.m NestedExceptions.m PropertyAttributeTest.m PropertyIntrospectionTest.m diff --git a/Test/Forward.m b/Test/Forward.m new file mode 100644 index 0000000..fa6c620 --- /dev/null +++ b/Test/Forward.m @@ -0,0 +1,73 @@ +#include "Test.h" +#include + +@interface Forward : Test +- (id)forwardingTargetForSelector: (SEL)sel; +@end + +id target; + +@implementation Forward +- (id)forwardingTargetForSelector: (SEL)sel +{ + return target; +} +@end + +@interface Forward2 : Test +@end + +@interface ForwardingTarget : Test +@end + +BOOL forwardingTargetCalled; + +@implementation ForwardingTarget +- (void)foo: (int)x +{ + assert(x == 42); + forwardingTargetCalled = YES; +} +@end +@implementation Forward2 +- (void)forward: (int)x +{ + [target foo: x]; +} +@end + +static id proxy_lookup(id receiver, SEL selector) +{ + if (class_respondsToSelector(object_getClass(receiver), @selector(forwardingTargetForSelector:))) + { + return [receiver forwardingTargetForSelector: selector]; + } + return nil; +} + +static struct objc_slot* forward(id receiver, SEL selector) +{ + __thread static struct objc_slot forwardingSlot; + if (class_respondsToSelector(object_getClass(receiver), @selector(forward:))) + { + forwardingSlot.method = class_getMethodImplementation(object_getClass(receiver), @selector(forward:)); + return &forwardingSlot; + } + assert(0); +} + +int main(void) +{ + objc_proxy_lookup = proxy_lookup; + __objc_msg_forward3 = forward; + target = [ForwardingTarget new]; + id proxy = [Forward new]; + [proxy foo: 42]; + [proxy dealloc]; + assert(forwardingTargetCalled == YES); + forwardingTargetCalled = NO; + proxy = [Forward2 new]; + [proxy foo: 42]; + [proxy dealloc]; + assert(forwardingTargetCalled == YES); +}