Re: Forwarding to Super
Re: Forwarding to Super
- Subject: Re: Forwarding to Super
- From: Herr Witten <email@hidden>
- Date: Thu, 1 Jul 2004 14:00:20 -0400
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:
//
// AFSuperInstance.h
//
// Michael Witten on Sat 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 <objc/objc-runtime.h>
@interface AFSuperInstance : NSObject
{
id _theObject;
struct objc_super _superInstance;
}
+ (id)superInstanceWithObject: (id)theObject;
- (id)initWithObject: (id)theObject;
@end
______________________________________________________________
//
// AFSuperInstance.m
//
// Michael Witten on Sat 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 "AFSuperInstance.h"
@implementation AFSuperInstance
+ (id)superInstanceWithObject: (id)theObject
{
return [[[[AFSuperInstance alloc] initWithObject: theObject]
retain] autorelease];
}
- (id)initWithObject: (id)theObject
{
self = [super init];
if (self)
{
_theObject = [theObject retain];
_superInstance.receiver = theObject;
_superInstance.class = [theObject superclass];
}
return self;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
return [_theObject methodSignatureForSelector: aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
NSMethodSignature * methodSignature = [anInvocation
methodSignature];
unsigned argumentCount = [methodSignature numberOfArguments];
SEL theSelector = [anInvocation selector];
Method theMethod = class_getInstanceMethod(_superInstance.class,
theSelector);
//unsigned argumentSizes[argumentCount];
unsigned argumentFrameLength = marg_prearg_size + ((7 +
method_getSizeOfArguments(theMethod)) & ~7);
void * argumentFrame = malloc(argumentFrameLength);
void * argPtr = argumentFrame;
unsigned argumentSize;
int index;
const char * type;
//int offsetIMP[argumentCount];
int offsetIMP;
unsigned offsetFrame = 0;
memmove(argPtr, _superInstance.receiver, sizeof(id));
NSLog([((id)argPtr) description]); //This works, or so it seems.
for (index = 1; index < argumentCount; index++)
{
//ArgumentSize is not useful.
//I don't think offsetIMP is large enough either, as it returns 4, 8,
etc...,
//which is the the size of ptrs, yet frameLength is 160-something
bytes for
//three arguments and the ptrs sizes just take up 12. Therefore, I
think
//a deep copy of sorts takes place.
argumentSize = method_getArgumentInfo(theMethod, index, &type,
&offsetIMP);
//I use offsetIMP here because its the only thing that has a decent
number.
argPtr = (void*)((char*)argumentFrame + offsetIMP);
if (type[0] == _C_ID)
{
id object;
[anInvocation getArgument: &object atIndex: index];
memmove(argPtr, object, sizeof(id)); //This doesn't do it; not
enough bytes are copied.
NSLog([((id)argPtr) description]); //This works, except its obvious
the whole thing isn't there, as certain fields are nil.
}
else
[anInvocation getArgument: argPtr atIndex: index];
offsetFrame += argumentSize; //This isn't used, because argumentSize
is not the byte size.
}
void* result = __builtin_apply((void(*)(void))theMethod->method_imp,
argumentFrame, argumentFrameLength);
[anInvocation setReturnValue: result];
}
@end
_______________________________________________
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.