* Source/NSObject:

- Tweaked NSObject to use atomic ops with LLVM as well as gcc (this
		  probably isn't actually needed)
		- Fixed SIGFPE problem on FreeBSD using proper interfaces instead of 
		an asm hack.
	* Removes various mframe things from being compiled when ffcall/libffi is
	used (mframe.m, NSConnection.m, NSInvocation.m)
	* Turned a nested function in make_strings.m into a macro.  

Tested by Gregory - blame him for any breakage...



git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@28462 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
David Chisnall 2009-08-15 21:44:21 +00:00
parent be2e15241e
commit 0fc392ad98
7 changed files with 129 additions and 100 deletions

View file

@ -1,3 +1,14 @@
2009-08-15 David Chisnall <theraven@gna.org>
* Source/NSObject:
- Tweaked NSObject to use atomic ops with LLVM as well as gcc (this
probably isn't actually needed)
- Fixed SIGFPE problem on FreeBSD using proper interfaces instead of
an asm hack.
* Removes various mframe things from being compiled when ffcall/libffi is
used (mframe.m, NSConnection.m, NSInvocation.m)
* Turned a nested function in make_strings.m into a macro.
2009-08-12 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSData.m: Remove some redundant methods and add checks for

View file

@ -37,6 +37,7 @@
#import "Foundation/NSEnumerator.h"
#import "GNUstepBase/preface.h"
#import "GNUstepBase/GSLock.h"
#import "Foundation/NSDebug.h"
/*
* Setup for inline operation of pointer map tables.
@ -1937,6 +1938,7 @@ static void retEncoder (DOContext *ctxt)
selector: (SEL)sel
argFrame: (arglist_t)argframe
{
#if !defined(USE_FFCALL) && !defined(USE_LIBFFI)
BOOL outParams;
BOOL needsResponse;
const char *type;
@ -2071,6 +2073,14 @@ static void retEncoder (DOContext *ctxt)
NSAssert(ctxt.decoder == nil, NSInternalInconsistencyException);
}
return retframe;
#else
/* If we've got to here then something has gone badly wrong. Most likely a
* mismatch between NSDistantObject and NSConnection implementations.
*/
NSAssert(NO, @"Legacy forwardForProxy:selector:argFrame: method called when"
" compiled with fcall/ffi.");
return 0; // Not reached.
#endif //!defined(USE_FFCALL) && !defined(USE_LIBFFI)
}
/*

View file

@ -660,82 +660,7 @@ _arg_addr(NSInvocation *inv, int index)
*/
- (void) invokeWithTarget: (id)anObject
{
id old_target;
retval_t returned;
IMP imp;
int stack_argsize;
CLEAR_RETURN_VALUE_IF_OBJECT;
_validReturn = NO;
/*
* A message to a nil object returns nil.
*/
if (anObject == nil)
{
_validReturn = YES;
memset(_retval, '\0', _info[0].size); /* Clear return value */
return;
}
NSAssert(_selector != 0, @"you must set the selector before invoking");
/*
* Temporarily set new target and copy it (and the selector) into the
* _cframe.
*/
old_target = RETAIN(_target);
[self setTarget: anObject];
_set_arg(self, 0, &_target);
_set_arg(self, 1, &_selector);
if (_sendToSuper == YES)
{
Super s;
#ifndef NeXT_RUNTIME
s.self = _target;
#else
s.receiver = _target;
#endif
if (GSObjCIsInstance(_target))
s.class = GSObjCSuper(GSObjCClass(_target));
else
s.class = GSObjCSuper((Class)_target);
imp = objc_msg_lookup_super(&s, _selector);
}
else
{
GSMethod method;
method = GSGetMethod((GSObjCIsInstance(_target)
? (id)GSObjCClass(_target)
: (id)_target),
_selector,
GSObjCIsInstance(_target),
YES);
imp = method_get_imp(method);
/*
* If fast lookup failed, we may be forwarding or something ...
*/
if (imp == 0)
imp = objc_msg_lookup(_target, _selector);
}
[self setTarget: old_target];
RELEASE(old_target);
stack_argsize = [_sig frameLength];
returned = __builtin_apply((void(*)(void))imp,
(arglist_t)_cframe, stack_argsize);
if (_info[0].size)
{
mframe_decode_return(_info[0].type, _retval, returned);
}
RETAIN_RETURN_VALUE;
_validReturn = YES;
[self subclassResponsibility: _cmd];
}
/**
@ -973,6 +898,8 @@ _arg_addr(NSInvocation *inv, int index)
@end
#if !defined(USE_FFCALL) && !defined(USE_LIBFFI)
#warning Using unreliable NSInvocation implementation. It is strongly recommended that you use libffi.
@implementation GSFrameInvocation
- (id) initWithArgframe: (arglist_t)frame selector: (SEL)aSelector
@ -1018,12 +945,92 @@ _arg_addr(NSInvocation *inv, int index)
}
return self;
}
- (void)invokeWithTarget: (id)anObject
{
id old_target;
retval_t returned;
IMP imp;
int stack_argsize;
CLEAR_RETURN_VALUE_IF_OBJECT;
_validReturn = NO;
/*
* A message to a nil object returns nil.
*/
if (anObject == nil)
{
_validReturn = YES;
memset(_retval, '\0', _info[0].size); /* Clear return value */
return;
}
NSAssert(_selector != 0, @"you must set the selector before invoking");
/*
* Temporarily set new target and copy it (and the selector) into the
* _cframe.
*/
old_target = RETAIN(_target);
[self setTarget: anObject];
_set_arg(self, 0, &_target);
_set_arg(self, 1, &_selector);
if (_sendToSuper == YES)
{
Super s;
#ifndef NeXT_RUNTIME
s.self = _target;
#else
s.receiver = _target;
#endif
if (GSObjCIsInstance(_target))
s.class = GSObjCSuper(GSObjCClass(_target));
else
s.class = GSObjCSuper((Class)_target);
imp = objc_msg_lookup_super(&s, _selector);
}
else
{
GSMethod method;
method = GSGetMethod((GSObjCIsInstance(_target)
? (id)GSObjCClass(_target)
: (id)_target),
_selector,
GSObjCIsInstance(_target),
YES);
imp = method_get_imp(method);
/*
* If fast lookup failed, we may be forwarding or something ...
*/
if (imp == 0)
imp = objc_msg_lookup(_target, _selector);
}
[self setTarget: old_target];
RELEASE(old_target);
stack_argsize = [_sig frameLength];
returned = __builtin_apply((void(*)(void))imp,
(arglist_t)_cframe, stack_argsize);
if (_info[0].size)
{
mframe_decode_return(_info[0].type, _retval, returned);
}
RETAIN_RETURN_VALUE;
_validReturn = YES;
}
- (void*) returnFrame: (arglist_t)argFrame
{
return mframe_handle_return(_info[0].type, _retval, argFrame);
}
@end
#endif
@implementation GSInvocationProxy

View file

@ -65,6 +65,9 @@
#ifdef HAVE_SYS_SIGNAL_H
#include <sys/signal.h>
#endif
#ifdef __FreeBSD__
#include <fenv.h>
#endif
#include "GSPrivate.h"
@ -219,7 +222,7 @@ typedef int32_t volatile *gsatomic_t;
#define GSAtomicDecrement(X) InterlockedDecrement((LONG volatile*)X)
#elif defined(USE_ATOMIC_BUILDINS) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
#elif defined(__llvm__) || (defined(USE_ATOMIC_BUILDINS) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)))
/* Use the GCC atomic operations with recent GCC versions */
typedef int32_t volatile *gsatomic_t;
@ -971,14 +974,7 @@ GSGarbageCollectorLog(char *msg, GC_word arg)
// Manipulate the FPU to add the exception mask. (Fixes SIGFPE
// problems on *BSD)
// Note this only works on x86
{
volatile short cw;
__asm__ volatile ("fstcw (%0)" : : "g" (&cw));
cw |= 1; /* Mask 'invalid' exception */
__asm__ volatile ("fldcw (%0)" : : "g" (&cw));
}
fedisableexcept(FE_INVALID);
#endif

View file

@ -803,6 +803,7 @@ mframe_dissect_call (arglist_t argframe, const char *type,
single data item (for distributed objects).
*/
#if !defined(USE_FFCALL) && !defined(USE_LIBFFI)
static inline id retframe_id(void *rframe)
{
__builtin_return (rframe);
@ -1795,3 +1796,4 @@ mframe_handle_return(const char* type, void* retval, arglist_t argframe)
return retframe;
}
#endif //!defined(USE_FFCALL) && !defined(USE_LIBFFI)

View file

@ -89,6 +89,23 @@ static int isname(unsigned char ch)
be any reason to).
*/
#define add_arg_ch(ch)\
{\
if (arg_len[num_args]+1>=arg_size[num_args])\
{\
arg_size[num_args]+=512;\
args[num_args]=realloc(args[num_args],arg_size[num_args]);\
if (!args[num_args])\
{\
NSLog(@"out of memory!\n");\
exit(1);\
}\
}\
args[num_args][arg_len[num_args]++]=ch;\
args[num_args][arg_len[num_args]]=0;\
}
static int ParseFile(const char *filename,NSMutableDictionary *tables)
{
FILE *f;
@ -120,21 +137,6 @@ static int ParseFile(const char *filename,NSMutableDictionary *tables)
int depth=0;
void add_arg_ch(int ch)
{
if (arg_len[num_args]+1>=arg_size[num_args])
{
arg_size[num_args]+=512;
args[num_args]=realloc(args[num_args],arg_size[num_args]);
if (!args[num_args])
{
NSLog(@"out of memory!\n");
exit(1);
}
}
args[num_args][arg_len[num_args]++]=ch;
args[num_args][arg_len[num_args]]=0;
}
filenamestr = [NSString stringWithCString: filename

View file

@ -1,3 +1,4 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
int main (void)