This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Obtaining first argument in Objective C method without explicitly using self ?


Hi,

I am working on a logging package for C and Objective-C .

To be able to keep syntax for logging macros the same in C functions and ObjC methods,
I am trying to do:


id myself = localVariableAvailable(self) ? self : NULL

I tried to look at the first character of __FUNCTION__ and (if it is '+' or '-')
call a combination of __builtin_return / __builtin_apply_args() to
retrieve the first argument.


This approach has two problems:

1. When used with -fomit-frame-pointer I had semi-reproducible crashes on x86_64 a method returns void.
(gcc 4.0.1, OS X 10.5.1)


2. It doesn't work with methods returning structs, which is probably because I use
a "fake" function (with a fixed return type) to be able to use __builtin_return.


	void *retself(void *self, void *_cmd)
	{
	  return self;
	}

void *getself(void *args)
{
__builtin_return( __builtin_apply((void (*)()) retself, args, 2 * sizeof(void*) ) );
}



[for reference, my complete test code for OS X 10.5 is attached below]


Can anyone think of a reliable approach to access "self" which will gracefully
yield NULL when used outside a method ?



Thanks for your time, kind regards,


Bjoern


--- 8< ---
/*
gcc -fomit-frame-pointer -Os -arch i386 -arch ppc -framework Foundation -mmacosx-version-min=10.4 -isysroot /Developer/SDKs/ MacOSX10.4u.sdk -o arg-rel arg.m
gcc -Os -arch x86_64 -arch ppc64 -framework Foundation -mmacosx- version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk -o arg-64- rel arg.m
*/
#include <stdio.h>
#import <Foundation/Foundation.h>


#define LP_ARGS __builtin_apply_args()
#define LP_FUNC __PRETTY_FUNCTION__


void *retself(void *self, void *_cmd) { return self; }

void *getself(void *args)
{
__builtin_return( __builtin_apply((void (*)()) retself, args, 2 * sizeof(void*) ) );
}



void logger(const char *tag, id realself, void *args) { id fakeself = (*tag =='+' || *tag == '-') ? getself(args) : NULL;

printf("%-40.40s: self: %p getself: %p\n", tag, realself, fakeself);
if( realself != fakeself ) { fprintf(stderr, "FAIL !!!!\n"); / *exit(1);*/ }
}


void cFuncVoid(void)
{
  logger(LP_FUNC, NULL, LP_ARGS);
}

int cFuncArgs(int a, int b)
{
  logger(LP_FUNC, NULL, LP_ARGS);
  return a+b;
}

@interface ArgTest : NSObject

- (float) xFromPoint: (NSPoint) p;
- (NSRect) rectFromPoint: (NSPoint) p width: (float) width height: (int) height;
- (void) nop;
+ (void) classNop;


@end

@implementation ArgTest

- (float) xFromPoint: (NSPoint) p
{
  logger(LP_FUNC, self, LP_ARGS);
  return p.x;
}

- (NSRect) rectFromPoint: (NSPoint) p width: (float) width height: (int) height
{
logger(LP_FUNC, self, LP_ARGS);
return NSMakeRect(p.x,p.y,width,height);
}


- (void) nop
{
  logger(LP_FUNC, self, LP_ARGS);
}


+ (void) classNop { logger(LP_FUNC, self, LP_ARGS); }



@end

int main(int argc, char **argv)
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

cFuncArgs(23,42);

ArgTest *a = [[ArgTest alloc] init];

float x = [a xFromPoint: NSMakePoint(1.2,3.4)];

printf("x: %f\n", x);

NSRect r = [a rectFromPoint: NSMakePoint(1.2,3.4) width: 5.6 height: 7.8];

printf("r: %s\n", [NSStringFromRect(r) UTF8String]);

[a nop];

[ArgTest classNop]; /* had semi-reproducible crashes with -fomit- frame-pointer on x86_64 */

[pool release];

  return 0;
}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]