Re: Forwarding to Super
Re: Forwarding to Super
- Subject: Re: Forwarding to Super
- From: Herr Witten <email@hidden>
- Date: Sun, 4 Jul 2004 00:50:42 -0400
Yes, this has been very helpful; I was certain that my methods would
work, so as a matter of pride and as opportunity to learn something I
kept trying to manipulate the constructed call. Fortunately, your
example revealed one very important thing to me: C is powerful, but
assembly hands it its ASSembly. WIth that, and a vigor I acquired after
seeing Spider Man 2 led me to a more condensed version with a slight
hack; I use the __builtin functions, a feat I accomplished after
noticing that the assembly sets register r3 by grabbing data from the
second word of the args data. Thus, the structure was revealed, and I
was able to completely bypass assembly (which, I guess means that C
kicked some ASSembly). Anyway, here is the code:
//
// SuperProxy.h
//
// Michael Witten on Thur 1 July 2004 43470 85
// Copyright (c) 2004 Michael Witten. All rights reserved.
// NOTE: You may reuse this code as long as the copyright remains
intact.
@interface SuperProxy : NSObject
{
id _theTarget;
Class _theClass;
BOOL _isObject;
}
+ (id)superProxyWithTarget: (id)theTarget;
- (id)initWithTarget: (id)theTarget;
@end
//
// SuperProxy.m
//
// Michael Witten on Thur 1 July 2004 43470 85
// Copyright (c) 2004 Michael Witten. All rights reserved.
// NOTE: You may reuse this code as long as the copyright remains
intact.
#import "SuperProxy.h"
#import <objc/objc-runtime.h>
static Method _method;
static IMP _method_imp_old;
id _imp_proxy(id theReceiver, SEL theSelector, ...)
{
struct objc_super superInstance;
superInstance.receiver = theReceiver;
superInstance.class = [theReceiver superclass];
void* args = __builtin_apply_args();
void* ptr = &superInstance;
memmove((int*)args + 1, &ptr, sizeof(int*));
__builtin_return(__builtin_apply((void(*)())objc_msgSendSuper, args,
method_getSizeOfArguments(_method)));
}
@implementation SuperProxy
+ (id)superProxyWithTarget: (id)theTarget
{
return [[[[SuperProxy alloc] initWithTarget: theTarget] retain]
autorelease];
}
- (id)initWithTarget: (id)theTarget
{
self = [super init];
if (self)
{
_theTarget = [theTarget retain];
_theClass = [_theTarget class];
_isObject = [_theTarget isMemberOfClass: _theClass];
}
return self;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
return [_theTarget methodSignatureForSelector: aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
SEL theSelector = [anInvocation selector];
if (_isObject)
_method = class_getInstanceMethod(_theClass, theSelector);
else
_method = class_getClassMethod(_theClass, theSelector);
_method_imp_old = _method->method_imp;
_method->method_imp = _imp_proxy;
[anInvocation invokeWithTarget: _theTarget];
_method->method_imp = _method_imp_old;
}
- (void)dealloc
{
[_theTarget release];
[super dealloc];
}
@end
Please send me feedback. The only trouble that is immediately obvious
is multithreading, but it seems that locks should take care of that.
Herr Witten
I hope you don't mind the somewhat crude humor.
On 2 Jul 2004, at 13:04, Louis C. Sacha wrote:
>
Hello...
>
>
This caught my interest (although I would suggest that this sort of
>
thing only be done as a last resort), and I played around with it a
>
bit and have some code that seems to work pretty well so far.
>
>
In case anyone wants to take a look, I've posted it temporarily at:
>
http://www.syndrome3d.com/temp/invoke_super.zip
>
>
The AncestorProxy class is similar to the AFSuperInstance class that
>
you were working on, although most of the functionality was added as a
>
category to NSInvocation and two runtime messaging functions.
>
>
>
Some of the details you were looking for are mentioned in the source
>
for the objective-C runtime (available as part of darwin),
>
specifically the comments in the "objc-msg-ppc.s" file.
>
>
>
Hope that helps,
>
>
Louis
>
>
> I've put this code together to illustrate what I'm trying to do, but
>
> there are two problems with it that I can surmise:
>
>
>
> 1. The argumentFrame is meant to hold pointers top the objects, while
>
> I
>
> am copying the structures, but this is unlikely, because the argument
>
> frame length is huge compared to the size of the pointers taken
>
> together.
>
>
>
> 2. The offset to each argument is certainly not being handled
>
> correctly, and I think this is because larger structures are being
>
> copied into the argumentFrame.
>
>
>
> Anyway, here is the code:
>
>
>
...
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.