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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux