Libffi support

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@13506 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fedor 2002-04-18 16:02:12 +00:00
parent 0a671f9dfb
commit d88dda825c
18 changed files with 1525 additions and 748 deletions

View file

@ -1,3 +1,18 @@
2002-04-18 Adam Fedor <fedor@gnu.org>
* Minimally working libffi support. Needs work.
* configure.in: Allow libffi to be enabled.
* Source/GSFFIInvocation.m: Rewrite.
* Source/NSConnection.m (-forwardInvocation:forProxy:): Add libffi
function.
* Source/NSInvocation.m: Fixup cifframe arg functions.
* Source/cifframe.m: Rewrite.
* Testing/nsinvocation.m: Bug fix.
* Documentation/coding-standards.texi: Remove info dir tag.
* Documentation/gnustep-base.texi: Idem.
* Resources/Languages/Slovak: New file.
Thu Apr 18 11:10:04 2002 Nicola Pero <n.pero@mi.flashnet.it>
* Headers/gnustep/base/NSObjCRuntime.h: Updated #defines and

View file

@ -4,9 +4,7 @@
@ifinfo
@format
START-INFO-DIR-ENTRY
* Coding: (coding). Coding Standards for GNUstep Libraries
END-INFO-DIR-ENTRY
@end format
@end ifinfo

View file

@ -13,9 +13,7 @@ prindex for protocols, and clindex for classes.
@ifinfo
@format
START-INFO-DIR-ENTRY
* gstep-base:: The GNUstep Base Library
END-INFO-DIR-ENTRY
@end format
@end ifinfo

View file

@ -6,9 +6,7 @@
@ifinfo
@format
START-INFO-DIR-ENTRY
* GNUstep Zones: (gnustep-zones). Memory management in GNUstep.
END-INFO-DIR-ENTRY
@end format
@end ifinfo

View file

@ -48,4 +48,7 @@
extern void
GSFFCallInvokeWithTargetAndImp(NSInvocation *inv, id anObject, IMP imp);
extern void
GSFFIInvokeWithTargetAndImp(NSInvocation *inv, id anObject, IMP imp);
#endif

View file

@ -0,0 +1,35 @@
/* Slovak */
{
NSLanguageName = "Slovak";
NSFormalName = "Slovensky";
NSLanguageCode = "SK";
NSParentContext = "Default";
NSCurrencySymbol = "Sk";
NSInternationalCurrencyString = SKK;
NSPositiveCurrencyFormatString = "9.999,00 $";
NSNegativeCurrencyFormatString = "-9.999,00 $";
NSDecimalDigits = ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
NSDecimalSeparator = ",";
NSDateFormatString = "%A, %B %d, %Y";
NSDateTimeOrdering = DMYH; /* resolve numbers in Day,Month,Year,Hour order */
NSEarlierTimeDesignations = ("predch\u00e1dzaj\u00faci", "posledn\u00fd", "minul\u00fd", "sp\u00e4\u0165");
NSHourNameDesignations = ((0, polnoc), (12, poludnie), (10, "r\u00e1no"), (14, poobede), (19, "ve\u010der"));
NSLaterTimeDesignations = ("bud\u00faci");
NSMonthNameArray = ("Janu\u00e1r", "Febru\u00e1r", Marec, "Apr\u00edl", "M\u00e1j", "J\u00fan", "J\u00fal", August, September, "Okt\u00f3ber", November, December);
NSNextDayDesignations = (zajtra);
NSNextNextDayDesignations = (pozajtra);
NSPriorDayDesignations = ("v\u010dera");
NSShortDateFormatString = "%d.%m.%Y"; /* "07.12.95" for example */
NSShortMonthNameArray = (Jan, Feb, Mar, Apr, "M\u00e1j", "J\u00fan", "J\u00fal", Aug, Sep, Okt, Nov, Dec);
NSShortTimeDateFormatString = "%d.%b.%Y %H:%M"; /* "07. Dec. 95 16:50 " for example */
NSShortWeekDayNameArray = (Ne, Po, Ut, St, "\u0160t", Pi, So);
NSThisDayDesignations = (dnes);
NSThousandsSeparator = ".";
NSTimeDateFormatString = "%a %b %d %Y %H:%M:%S %Z";
NSTimeFormatString = "%H:%M:%S";
NSWeekDayNameArray = ("Nede\u013ea", Pondelok, Utorok, Streda, "\u0160tvrtok", Piatok, Sobota);
NSYearMonthWeekDesignations = (rok, mesiac, "t\u00fd\u017ede\u0148");
}

View file

@ -1057,3 +1057,4 @@ GSInvocationCallback (void *callback_data, va_alist args)
return out_parameters;
}
@end

View file

@ -2,7 +2,7 @@
Copyright (C) 2000 Free Software Foundation, Inc.
Written: Adam Fedor <fedor@gnu.org>
Date: Nov 2000
Date: Apr 2002
This file is part of the GNUstep Base Library.
@ -20,81 +20,536 @@
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <Foundation/NSException.h>
#include <Foundation/NSCoder.h>
#include <Foundation/NSDistantObject.h>
#include <base/GSInvocation.h>
#include <config.h>
#include <mframe.h>
#include <objc/objc-api.h>
#include "cifframe.h"
/* The FFI library doesn't have closures (well it does, but only for ix86), so
we still use a lot of the argframe (mframe) functions for things like
forwarding
*/
#ifndef INLINE
#define INLINE inline
#endif
@implementation GSFFIInvocation
#if defined(ALPHA) || (defined(MIPS) && (_MIPS_SIM == _ABIN32))
typedef long long smallret_t;
#else
typedef int smallret_t;
#endif
- (id) initWithArgframe: (arglist_t)frame selector: (SEL)aSelector
typedef struct _NSInvocation_t {
@defs(NSInvocation)
} NSInvocation_t;
/* Function that implements the actual forwarding */
typedef void (*ffi_closure_fun) (ffi_cif*,void*,void**,void*);
void GSFFIInvocationCallback(ffi_cif*, void*, void **, void*);
/*
* If we are using the GNU ObjC runtime we could
* simplify this function quite a lot because this
* function is already present in the ObjC runtime.
* However, it is not part of the public API, so
* we work around it.
*/
static INLINE Method_t
gs_method_for_receiver_and_selector (id receiver, SEL sel)
{
const char *types;
NSMethodSignature *newSig;
types = sel_get_type(aSelector);
if (types == 0)
if (receiver)
{
types = sel_get_type(sel_get_any_typed_uid(sel_get_name(aSelector)));
if (object_is_instance (receiver))
{
return class_get_instance_method (object_get_class
(receiver), sel);
}
else if (object_is_class (receiver))
{
return class_get_class_method (object_get_meta_class
(receiver), sel);
}
}
if (types == 0)
{
[NSException raise: NSInvalidArgumentException
format: @"Couldn't find encoding type for selector %s.",
sel_get_name(aSelector)];
}
newSig = [NSMethodSignature signatureWithObjCTypes: types];
self = [self initWithMethodSignature: newSig];
if (self)
return METHOD_NULL;
}
/*
* Selectors are not unique, and not all selectors have
* type information. This method tries to find the
* best equivalent selector with type information.
*
* the conversion sel -> name -> sel
* is not what we want. However
* I can not see a way to dispose of the
* name, except if we can access the
* internal data structures of the runtime.
*
* If we can access the private data structures
* we can also check for incompatible
* return types between all equivalent selectors.
*/
static INLINE SEL
gs_find_best_typed_sel (SEL sel)
{
if (!sel_get_type (sel))
{
[self setSelector: aSelector];
/*
* Copy the _cframe we were given.
*/
if (frame)
const char *name = sel_get_name (sel);
if (name)
{
int i;
mframe_get_arg(frame, &_info[1], &_target);
for (i = 1; i <= _numArgs; i++)
{
mframe_get_arg(frame, &_info[i],
((cifframe_t *)_cframe)->values[i-1]);
}
SEL tmp_sel = sel_get_any_typed_uid (name);
if (sel_get_type (tmp_sel))
return tmp_sel;
}
}
return self;
return sel;
}
/*
* This is the de_signated initialiser.
* Take the receiver into account for finding the best
* selector. That is, we look if the receiver
* implements the selector and the implementation
* selector has type info. If both conditions
* are satisfied, return this selector.
*
* In all other cases fallback
* to gs_find_best_typed_sel ().
*/
static INLINE SEL
gs_find_by_receiver_best_typed_sel (id receiver, SEL sel)
{
if (sel_get_type (sel))
return sel;
if (receiver)
{
Method_t method;
method = gs_method_for_receiver_and_selector (receiver, sel);
/* CHECKME: Can we assume that:
(a) method_name is a selector (compare libobjc header files)
(b) this selector IS really typed?
At the moment I assume (a) but not (b)
not assuming (b) is the reason for
calling gs_find_best_typed_sel () even
if we have an implementation.
*/
if (method)
sel = method->method_name;
}
return gs_find_best_typed_sel (sel);
}
@implementation GSFFIInvocation
static IMP gs_objc_msg_forward (SEL sel)
{
const char *sel_type;
cifframe_t *cframe;
ffi_closure *cclosure;
NSMethodSignature *sig;
/* Determine the method types so we can construct the frame. We may not
get the right one, though. What to do then? Perhaps it can be fixed up
in the callback, but only under limited circumstances.
*/
sel = gs_find_best_typed_sel (sel);
sel_type = sel_get_type (sel);
sig = nil;
if (sel_type)
{
sig = [NSMethodSignature signatureWithObjCTypes: sel_type];
}
NSCAssert1(sig, @"No signature for selector %@", NSStringFromSelector(sel));
/* Construct the frame and closure. */
/* Note: We alloc cframe here, but it's passed to GSFFIInvocationCallback
where it becomes owned by the callback invocation, so we don't have to
worry about freeing it */
cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments], NULL);
/* FIXME: But how to we free this? */
cclosure = NSZoneCalloc(NSDefaultMallocZone(), sizeof(ffi_closure), 1);
if (cframe == NULL || cclosure == NULL)
{
[NSException raise: NSMallocException format: @"Allocating closure"];
}
if (ffi_prep_closure(cclosure, &(cframe->cif),
GSFFIInvocationCallback, cframe) != FFI_OK)
{
[NSException raise: NSGenericException format: @"Preping closure"];
}
return (IMP)cclosure;
}
+ (void) load
{
__objc_msg_forward = gs_objc_msg_forward;
}
- (id) initWithArgframe: (arglist_t)frame selector: (SEL)aSelector
{
/* We should never get here */
NSDeallocateObject(self);
[NSException raise: NSInternalInconsistencyException
format: @"Runtime incorrectly configured to pass argframes"];
return nil;
}
/*
* This is the designated initialiser.
*/
- (id) initWithMethodSignature: (NSMethodSignature*)aSignature
{
_sig = RETAIN(aSignature);
_numArgs = [aSignature numberOfArguments];
_info = [aSignature methodInfo];
_cframe = cifframe_from_sig([_sig methodType], &_retval);
if (_retval == 0 && _info[0].size > 0)
{
_retval = NSZoneMalloc(NSDefaultMallocZone(), _info[0].size);
}
_cframe = cifframe_from_info(_info, _numArgs, &_retval);
return self;
}
/* Initializer used when we get a callback. uses the data provided by
the callback. The cifframe was allocated by the forwarding function,
but we own it now so we can free it */
- (id) initWithCallback: (ffi_cif *)cif
returnp: (void *)retp
values: (void **)vals
frame: (cifframe_t *)frame
signature: (NSMethodSignature*)aSignature
{
int i, offset;
_sig = RETAIN(aSignature);
_numArgs = [aSignature numberOfArguments];
_info = [aSignature methodInfo];
_cframe = frame;
((cifframe_t *)_cframe)->cif = *cif;
((cifframe_t *)_cframe)->values = vals;
/* Insert the values into the value array.
FIXME: I don't think this is correct for structures. */
offset = 0;
for (i = 0; i < ((cifframe_t *)_cframe)->nargs; i++)
{
((cifframe_t *)_cframe)->values[i] = *vals + offset;
offset += MAX(((cifframe_t *)_cframe)->arg_types[i]->size,
sizeof(smallret_t));
}
_retval = retp;
return self;
}
/*
* This is implemented as a function so it can be used by other
* routines (like the DO forwarding)
*/
void
GSFFIInvokeWithTargetAndImp(NSInvocation *_inv, id anObject, IMP imp)
{
int i;
NSInvocation_t *inv = (NSInvocation_t*)_inv;
/* Some arguments need to be promoted to be passed correctly */
for (i = 2; i < inv->_numArgs; i++)
{
const char *type = inv->_info[i+1].type;
cifframe_encode_arg(type, cifframe_arg_addr(inv->_cframe, i));
}
/* Do it */
ffi_call(inv->_cframe, imp, (inv->_retval),
((cifframe_t *)inv->_cframe)->values);
/* Don't decode the return value here */
}
- (void) invokeWithTarget: (id)anObject
{
id old_target;
IMP imp;
/*
* A message to a nil object returns nil.
*/
if (anObject == nil)
{
if (_retval)
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];
cifframe_set_arg((cifframe_t *)_cframe, 0, &_target, _info[1].size);
cifframe_set_arg((cifframe_t *)_cframe, 1, &_selector, _info[2].size);
if (_sendToSuper == YES)
{
Super s;
s.self = _target;
if (GSObjCIsInstance(_target))
s.class = class_get_super_class(GSObjCClass(_target));
else
s.class = class_get_super_class((Class)_target);
imp = objc_msg_lookup_super(&s, _selector);
}
else
{
imp = method_get_imp(object_is_instance(_target) ?
class_get_instance_method(
((struct objc_class*)_target)->class_pointer, _selector)
: class_get_class_method(
((struct objc_class*)_target)->class_pointer, _selector));
/*
* 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);
GSFFIInvokeWithTargetAndImp(self, anObject, imp);
/* Decode the return value */
if (*_info[0].type != _C_VOID)
cifframe_decode_arg(_info[0].type, _retval);
_validReturn = YES;
}
- (void*) returnFrame: (arglist_t)argFrame
{
return mframe_handle_return(_info[0].type, _retval, argFrame);
return _retval;
}
@end
void
GSFFIInvocationCallback(ffi_cif *cif, void *retp, void **args, void *user)
{
id obj;
SEL selector;
GSFFIInvocation *invocation;
NSMethodSignature *sig;
Method_t fwdInvMethod;
memcpy(&obj, *args, sizeof(id));
memcpy(&selector, *args+sizeof(id *), sizeof(SEL));
fwdInvMethod = gs_method_for_receiver_and_selector
(obj, @selector (forwardInvocation:));
if (!fwdInvMethod)
{
NSCAssert2 (0, @"GSFFIInvocation: Class '%s' does not respond"
@" to forwardInvocation: for '%s'",
object_get_class_name (obj), sel_get_name(selector));
}
selector = gs_find_by_receiver_best_typed_sel (obj, selector);
sig = nil;
if (sel_get_type (selector))
{
sig = [NSMethodSignature signatureWithObjCTypes: sel_get_type(selector)];
}
if (!sig)
{
sig = [obj methodSignatureForSelector: selector];
}
NSCAssert1(sig, @"No signature for selector %@",
NSStringFromSelector(selector));
invocation = [[GSFFIInvocation alloc] initWithCallback: cif
returnp: retp
values: args
frame: user
signature: sig];
AUTORELEASE(invocation);
[invocation setTarget: obj];
[invocation setSelector: selector];
/*
* Now do it.
* The next line is equivalent to
*
* [obj forwardInvocation: invocation];
*
* but we have already the Method_t for forwardInvocation
* so the line below is somewhat faster. */
fwdInvMethod->method_imp (obj, fwdInvMethod->method_name, invocation);
/* We need to (re)encode the return type for it's trip back. */
if (retp)
cifframe_encode_arg([sig methodReturnType], retp);
}
@implementation NSInvocation (DistantCoding)
/* An internal method used to help NSConnections code invocations
to send over the wire */
- (BOOL) encodeWithDistantCoder: (NSCoder*)coder passPointers: (BOOL)passp
{
int i;
BOOL out_parameters = NO;
const char *type = [_sig methodType];
[coder encodeValueOfObjCType: @encode(char*) at: &type];
for (i = 0; i < _numArgs; i++)
{
int flags = _info[i+1].qual;
const char *type = _info[i+1].type;
void *datum;
if (i == 0)
{
datum = &_target;
}
else if (i == 1)
{
datum = &_selector;
}
else
{
datum = cifframe_arg_addr((cifframe_t *)_cframe, i);
}
/*
* Decide how, (or whether or not), to encode the argument
* depending on its FLAGS and TYPE. Only the first two cases
* involve parameters that may potentially be passed by
* reference, and thus only the first two may change the value
* of OUT_PARAMETERS.
*/
switch (*type)
{
case _C_ID:
if (flags & _F_BYCOPY)
{
[coder encodeBycopyObject: *(id*)datum];
}
#ifdef _F_BYREF
else if (flags & _F_BYREF)
{
[coder encodeByrefObject: *(id*)datum];
}
#endif
else
{
[coder encodeObject: *(id*)datum];
}
break;
case _C_CHARPTR:
/*
* Handle a (char*) argument.
* If the char* is qualified as an OUT parameter, or if it
* not explicitly qualified as an IN parameter, then we will
* have to get this char* again after the method is run,
* because the method may have changed it. Set
* OUT_PARAMETERS accordingly.
*/
if ((flags & _F_OUT) || !(flags & _F_IN))
{
out_parameters = YES;
}
/*
* If the char* is qualified as an IN parameter, or not
* explicity qualified as an OUT parameter, then encode
* it.
*/
if ((flags & _F_IN) || !(flags & _F_OUT))
{
[coder encodeValueOfObjCType: type at: datum];
}
break;
case _C_PTR:
/*
* If the pointer's value is qualified as an OUT parameter,
* or if it not explicitly qualified as an IN parameter,
* then we will have to get the value pointed to again after
* the method is run, because the method may have changed
* it. Set OUT_PARAMETERS accordingly.
*/
if ((flags & _F_OUT) || !(flags & _F_IN))
{
out_parameters = YES;
}
if (passp)
{
if ((flags & _F_IN) || !(flags & _F_OUT))
{
[coder encodeValueOfObjCType: type at: datum];
}
}
else
{
/*
* Handle an argument that is a pointer to a non-char. But
* (void*) and (anything**) is not allowed.
* The argument is a pointer to something; increment TYPE
* so we can see what it is a pointer to.
*/
type++;
/*
* If the pointer's value is qualified as an IN parameter,
* or not explicity qualified as an OUT parameter, then
* encode it.
*/
if ((flags & _F_IN) || !(flags & _F_OUT))
{
[coder encodeValueOfObjCType: type at: *(void**)datum];
}
}
break;
case _C_STRUCT_B:
case _C_UNION_B:
case _C_ARY_B:
/*
* Handle struct and array arguments.
* Whether DATUM points to the data, or points to a pointer
* that points to the data, depends on the value of
* CALLFRAME_STRUCT_BYREF. Do the right thing
* so that ENCODER gets a pointer to directly to the data.
*/
[coder encodeValueOfObjCType: type at: datum];
break;
default:
/* Handle arguments of all other types. */
[coder encodeValueOfObjCType: type at: datum];
}
}
/*
* Return a BOOL indicating whether or not there are parameters that
* were passed by reference; we will need to get those values again
* after the method has finished executing because the execution of
* the method may have changed them.
*/
return out_parameters;
}
@end

View file

@ -2004,7 +2004,9 @@ static void retEncoder (DOContext *ctxt)
}
else
{
#ifdef USE_FFCALL
#ifdef USE_LIBFFI
cifframe_build_return (inv, type, outParams, retDecoder, &ctxt);
#elif defined(USE_FFCALL)
callframe_build_return (inv, type, outParams, retDecoder, &ctxt);
#endif
/* Make sure we processed all arguments, and dismissed the IP.

View file

@ -37,7 +37,6 @@
#include "callframe.h"
#endif
static Class NSInvocation_abstract_class;
static Class NSInvocation_concrete_class;
@ -47,13 +46,15 @@ static Class NSInvocation_concrete_class;
static inline void
_get_arg(NSInvocation *inv, int index, void *buffer)
{
cifframe_get_arg((cifframe_t *)inv->_cframe, index, buffer);
cifframe_get_arg((cifframe_t *)inv->_cframe, index, buffer,
inv->_info[index+1].size);
}
static inline void
_set_arg(NSInvocation *inv, int index, void *buffer)
{
cifframe_set_arg((cifframe_t *)inv->_cframe, index, buffer);
cifframe_set_arg((cifframe_t *)inv->_cframe, index, buffer,
inv->_info[index+1].size);
}
static inline void *
@ -169,7 +170,7 @@ _arg_addr(NSInvocation *inv, int index)
#if defined(USE_LIBFFI)
if (_cframe)
{
cifframe_free((cifframe_t *)_cframe);
NSZoneFree(NSDefaultMallocZone(), _cframe);
_retval = 0; // Part of _cframe
}
#elif defined(USE_FFCALL)
@ -478,21 +479,12 @@ _arg_addr(NSInvocation *inv, int index)
stack_argsize = [_sig frameLength];
#ifdef USE_LIBFFI
ffi_call(&((cifframe_t *)_cframe)->cif, (void(*)(void))imp, _retval,
((cifframe_t *)_cframe)->values);
if (_info[0].size)
{
cifframe_decode_return(_info[0].type, _retval);
}
#else
returned = __builtin_apply((void(*)(void))imp,
(arglist_t)_cframe, stack_argsize);
if (_info[0].size)
{
mframe_decode_return(_info[0].type, _retval, returned);
}
#endif
_validReturn = YES;
}
@ -659,9 +651,6 @@ _arg_addr(NSInvocation *inv, int index)
unsigned size = _info[i].size;
void *datum;
#ifdef USE_LIBFFI
size = ((cifframe_t *)_cframe)->args[i-1]->size;
#endif
datum = _arg_addr(self, i-1);
#define CASE_TYPE(_C,_T) case _C: *(_T*)datum = va_arg (ap, _T); break

View file

@ -35,11 +35,6 @@ typedef long long smallret_t;
typedef int smallret_t;
#endif
/* Return the number of arguments that the method MTH expects. Note
that all methods need two implicit arguments `self' and `_cmd'.
From mframe.m */
extern int method_types_get_number_of_arguments (const char *type);
extern BOOL sel_types_match(const char* t1, const char* t2);
callframe_t *

View file

@ -26,24 +26,32 @@
#define cifframe_h_INCLUDE
#include <ffi.h>
#include <base/preface.h>
#include <Foundation/NSMethodSignature.h>
#include <base/DistributedObjects.h>
typedef struct _cifframe_t {
ffi_cif cif;
int nargs;
ffi_type *rtype;
ffi_type **args;
ffi_type **arg_types;
void **values;
} cifframe_t;
extern cifframe_t *cifframe_from_sig (const char *typePtr, void **retval);
extern void cifframe_free(cifframe_t *cframe);
extern void cifframe_set_arg(cifframe_t *cframe, int index, void *buffer);
extern void cifframe_get_arg(cifframe_t *cframe, int index, void *buffer);
extern cifframe_t *cifframe_from_info (NSArgumentInfo *info, int numargs,
void **retval);
extern void cifframe_set_arg(cifframe_t *cframe, int index, void *buffer,
int size);
extern void cifframe_get_arg(cifframe_t *cframe, int index, void *buffer,
int size);
extern void *cifframe_arg_addr(cifframe_t *cframe, int index);
extern BOOL cifframe_decode_return (const char *type, void* buffer);
extern BOOL cifframe_decode_arg (const char *type, void* buffer);
extern BOOL cifframe_encode_arg (const char *type, void* buffer);
extern void cifframe_do_call (DOContext *ctxt,
void(*decoder)(DOContext*),
void(*encoder)(DOContext*));
extern void cifframe_build_return (NSInvocation *inv,
const char *type,
BOOL out_parameters,
void(*decoder)(DOContext*),
DOContext* ctxt);
#endif

File diff suppressed because it is too large Load diff

View file

@ -36,7 +36,7 @@
#
# Additional flags to pass to the preprocessor
ADDITIONAL_CPPFLAGS =
ADDITIONAL_CPPFLAGS =
# Additional flags to pass to the Objective-C compiler
ADDITIONAL_OBJCFLAGS = -g
@ -54,7 +54,6 @@ ADDITIONAL_LDFLAGS =
# Additional library directories the linker should search
ADDITIONAL_LIB_DIRS = -L../Source/$(GNUSTEP_OBJ_DIR)
ifeq ($(GNUSTEP_TARGET_OS),mingw32)
BUNDLE_LIBS += -lgnustep-base -lobjc
endif

View file

@ -164,6 +164,8 @@ typedef struct {
d = [NSArchiver archivedDataWithRootObject: i];
i = [NSUnarchiver unarchiveObjectWithData: d];
l = [[i methodSignature] methodReturnLength];
if (l < sizeof(void *))
l = sizeof(void *);
b = (void *)objc_malloc(l);
[i getReturnValue: b];
[inv setReturnValue: b];
@ -194,8 +196,10 @@ main ()
id p;
NSAutoreleasePool *arp = [NSAutoreleasePool new];
printf("Starting\n");
t = [Target new];
p = [[MyProxy alloc] initWithTarget: t];
printf("Calling proxy\n");
[p loopInt: 1];
#define SETUP(X) \

View file

@ -7,7 +7,7 @@ GCC_VERSION=2.8.0
# The version number of this release.
MAJOR_VERSION=1
MINOR_VERSION=3
SUBMINOR_VERSION=0
SUBMINOR_VERSION=1
GNUSTEP_BASE_VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${SUBMINOR_VERSION}
VERSION=${GNUSTEP_BASE_VERSION}

530
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -852,12 +852,11 @@ AC_ARG_ENABLE(libffi,
[ --enable-libffi Enable use of libffi library],,
enable_libffi=no)
if test $enable_libffi = yes; then
AC_WARN(libffi support disabled)
echo
echo "GNUstep requires more functionality than the ffi library"
echo "currently supports ... please use ffcall instead."
echo "libffi support will be added when the ffi library improves"
enable_libffi=no
echo "WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "The libffi library is not fully supported in GNUstep"
echo "please use ffcall instead, unless you would like to help."
echo "debug it. Use with caution."
echo "WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
fi
AC_ARG_ENABLE(ffcall,