mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
* 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:
parent
be2e15241e
commit
0fc392ad98
7 changed files with 129 additions and 100 deletions
11
ChangeLog
11
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <objc/objc.h>
|
||||
#include <objc/objc-api.h>
|
||||
|
||||
int main (void)
|
||||
|
|
Loading…
Reference in a new issue