mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
a bit step towards removing obsolete mframe code.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@28774 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
da7a20d13d
commit
715bdcaa0a
18 changed files with 134 additions and 1987 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
|||
2009-10-04 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/GNUmakefile:
|
||||
* Source/NSMethodSignature.m:
|
||||
* Source/GSFFCallInvocation.m:
|
||||
* Source/mframe/mframe.head:
|
||||
* Source/GSFFIInvocation.m:
|
||||
* Source/NSInvocation.m:
|
||||
* Source/cifframe.h:
|
||||
* Source/mframe.m:
|
||||
* Source/cifframe.m:
|
||||
* Source/NSConnection.m:
|
||||
* Source/callframe.h:
|
||||
* Source/NSObjCRuntime.m:
|
||||
* Source/callframe.m:
|
||||
* Headers/Additions/GNUstepBase/DistributedObjects.h:
|
||||
* Headers/Additions/GNUstepBase/preface.h.in:
|
||||
Remove lots of obsolete code as part of the ong term process of
|
||||
scrapping the old mframe stuff.
|
||||
|
||||
2009-10-04 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/cifframe.h: Remove unused code
|
||||
|
|
|
@ -88,24 +88,4 @@ enum {
|
|||
- (id) conversation: (NSPort*)receivePort;
|
||||
@end
|
||||
|
||||
/*
|
||||
* A structure for passing context information using in encoding/decoding
|
||||
* arguments for DO
|
||||
*/
|
||||
typedef struct {
|
||||
const char *type; // The type of the data
|
||||
int flags; // Type qualifier flags
|
||||
void *datum; // Where to get/store data
|
||||
NSConnection *connection; // The connection in use
|
||||
NSPortCoder *decoder; // The coder to use
|
||||
NSPortCoder *encoder; // The coder to use
|
||||
unsigned seq; // Sequence number
|
||||
/*
|
||||
* These next fields can store allocated memory that will need to be
|
||||
* tidied up iff an exception occurs before they can be tidied normally.
|
||||
*/
|
||||
void *datToFree; // Data needing NSZoneFree()
|
||||
id objToFree; // Data needing NSDeallocateObject()
|
||||
} DOContext;
|
||||
|
||||
#endif /* __DistributedObjects_h */
|
||||
|
|
|
@ -1,294 +0,0 @@
|
|||
/* Definitions to allow compilation of GNU objc code with NeXT runtime
|
||||
and the reverse.
|
||||
|
||||
Copyright (C) 1993,1994,1996,2003 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
/* This file is by no means complete. */
|
||||
|
||||
#ifndef __objc_gnu2next_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __objc_gnu2next_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if NeXT_RUNTIME
|
||||
|
||||
#include <objc/objc-class.h>
|
||||
#include <objc/objc-runtime.h>
|
||||
#include <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Disable builtin functions for gcc < 3.x since it triggers a bad bug
|
||||
(even some 3.x versions may have this bug). */
|
||||
#if __GNUC__ < 3
|
||||
#define __builtin_apply(a,b,c) 0
|
||||
#define __builtin_apply_args() 0
|
||||
#define __builtin_return(a) 0
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
char *arg_ptr;
|
||||
char arg_regs[sizeof (char*)];
|
||||
} *arglist_t; /* argument frame */
|
||||
//#define arglist_t marg_list
|
||||
#define retval_t void*
|
||||
typedef void(*apply_t)(void); /* function pointer */
|
||||
#define TypedStream void*
|
||||
|
||||
#define METHOD_NULL (struct objc_method *)0
|
||||
|
||||
#define _CLS_META CLS_META
|
||||
#define _CLS_CLASS CLS_CLASS
|
||||
|
||||
#define class_pointer isa
|
||||
typedef struct objc_super Super;
|
||||
|
||||
#define class_create_instance(CLASS) class_createInstance(CLASS, 0)
|
||||
#define class_get_instance_method class_getInstanceMethod
|
||||
#define class_add_method_list class_addMethods
|
||||
#define class_set_version class_setVersion
|
||||
#define class_get_version class_getVersion
|
||||
#define class_pose_as class_poseAs
|
||||
#define method_get_sizeof_arguments method_getSizeOfArguments
|
||||
#define objc_lookup_class objc_lookUpClass
|
||||
#define objc_get_class objc_getClass
|
||||
|
||||
#define sel_register_name sel_registerName
|
||||
#define sel_is_mapped sel_isMapped
|
||||
#define sel_get_name sel_getName
|
||||
#define sel_get_any_uid sel_getUid
|
||||
#define sel_get_uid sel_getUid
|
||||
#define sel_eq(s1, s2) (s1 == s2)
|
||||
|
||||
#define __objc_update_dispatch_table_for_class _objc_flush_caches
|
||||
|
||||
/* There's no support for typed sels in NeXT. These may not work */
|
||||
#define sel_get_typed_uid(_s, _t) sel_getUid(_s)
|
||||
#define sel_get_any_typed_uid sel_getUid
|
||||
#define sel_register_typed_name(_s, _t) sel_registerName(_s)
|
||||
#define sel_get_type(_s) (NULL)
|
||||
|
||||
#define class_get_class_name(CLASSPOINTER) \
|
||||
(((struct objc_class*)(CLASSPOINTER))->name)
|
||||
#define object_get_class(OBJECT) \
|
||||
(((struct objc_class*)(OBJECT))->isa)
|
||||
#define class_get_super_class(CLASSPOINTER) \
|
||||
(((struct objc_class*)(CLASSPOINTER))->super_class)
|
||||
#define object_get_super_class(OBJECT) \
|
||||
(((struct objc_class*)(object_get_class(OBJECT)))->super_class)
|
||||
#define object_get_class_name(OBJECT) \
|
||||
(((struct objc_class*)(object_get_class(OBJECT)))->name)
|
||||
|
||||
#define __objc_responds_to(OBJECT,SEL) \
|
||||
(class_getInstanceMethod(object_get_class(OBJECT), SEL) != METHOD_NULL)
|
||||
#define CLS_ISCLASS(CLASSPOINTER) \
|
||||
((((struct objc_class*)(CLASSPOINTER))->info) & CLS_CLASS)
|
||||
#define CLS_ISMETA(CLASSPOINTER) \
|
||||
((((struct objc_class*)(CLASSPOINTER))->info) & CLS_META)
|
||||
#define objc_msg_lookup(OBJ,SEL) \
|
||||
(class_getInstanceMethod(object_get_class(OBJ), SEL)->method_imp)
|
||||
#define objc_msg_lookup_super(OBJ,SEL) \
|
||||
(class_getInstanceMethod(object_get_class(OBJ), SEL)->method_imp)
|
||||
|
||||
#define objc_msg_sendv next_objc_msg_sendv
|
||||
|
||||
extern id next_objc_msg_sendv(id self, SEL op, void* arg_frame);
|
||||
|
||||
#define OBJC_READONLY 1
|
||||
#define OBJC_WRITEONLY 2
|
||||
|
||||
/*
|
||||
** Standard functions for memory allocation and disposal.
|
||||
** Users should use these functions in their ObjC programs so
|
||||
** that they work properly with garbage collectors as well as
|
||||
** can take advantage of the exception/error handling available.
|
||||
*/
|
||||
void *
|
||||
objc_malloc(size_t size);
|
||||
|
||||
void *
|
||||
objc_atomic_malloc(size_t size);
|
||||
|
||||
void *
|
||||
objc_valloc(size_t size);
|
||||
|
||||
void *
|
||||
objc_realloc(void *mem, size_t size);
|
||||
|
||||
void *
|
||||
objc_calloc(size_t nelem, size_t size);
|
||||
|
||||
void
|
||||
objc_free(void *mem);
|
||||
|
||||
static inline BOOL
|
||||
class_is_class(Class class)
|
||||
{
|
||||
return CLS_ISCLASS(class);
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
object_is_class(id object)
|
||||
{
|
||||
return CLS_ISCLASS((Class)object);
|
||||
}
|
||||
|
||||
static inline long
|
||||
class_get_instance_size(Class class)
|
||||
{
|
||||
return CLS_ISCLASS(class)?class->instance_size:0;
|
||||
}
|
||||
|
||||
static inline IMP
|
||||
method_get_imp(Method method)
|
||||
{
|
||||
return (method!=0)?method->method_imp:(IMP)0;
|
||||
}
|
||||
|
||||
static inline IMP
|
||||
get_imp(Class class, SEL aSel)
|
||||
{
|
||||
return method_get_imp(class_getInstanceMethod(class, aSel));
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
object_is_instance(id object)
|
||||
{
|
||||
return (object!=nil)&&CLS_ISCLASS(object->class_pointer);
|
||||
}
|
||||
|
||||
/*
|
||||
** Hook functions for memory allocation and disposal.
|
||||
** This makes it easy to substitute garbage collection systems
|
||||
** such as Boehm's GC by assigning these function pointers
|
||||
** to the GC's allocation routines. By default these point
|
||||
** to the ANSI standard malloc, realloc, free, etc.
|
||||
**
|
||||
** Users should call the normal objc routines above for
|
||||
** memory allocation and disposal within their programs.
|
||||
*/
|
||||
extern void *(*_objc_malloc)(size_t);
|
||||
extern void *(*_objc_atomic_malloc)(size_t);
|
||||
extern void *(*_objc_valloc)(size_t);
|
||||
extern void *(*_objc_realloc)(void *, size_t);
|
||||
extern void *(*_objc_calloc)(size_t, size_t);
|
||||
extern void (*_objc_free)(void *);
|
||||
|
||||
|
||||
/* threading functions */
|
||||
typedef void *objc_mutex_t;
|
||||
|
||||
objc_mutex_t objc_mutex_allocate (void);
|
||||
int objc_mutex_deallocate (objc_mutex_t mutex);
|
||||
int objc_mutex_lock (objc_mutex_t mutex);
|
||||
int objc_mutex_unlock (objc_mutex_t mutex);
|
||||
int objc_mutex_trylock (objc_mutex_t mutex);
|
||||
|
||||
/* encoding functions */
|
||||
extern int objc_sizeof_type(const char* type);
|
||||
extern int objc_alignof_type(const char* type);
|
||||
extern int objc_aligned_size (const char* type);
|
||||
extern int objc_promoted_size (const char* type);
|
||||
extern const char *objc_skip_type_qualifiers (const char* type);
|
||||
extern const char *objc_skip_typespec (const char* type);
|
||||
extern const char *objc_skip_argspec (const char* type);
|
||||
extern unsigned objc_get_type_qualifiers (const char* type);
|
||||
extern BOOL sel_types_match (const char* t1, const char* t2);
|
||||
|
||||
/* Error handling */
|
||||
extern void objc_error(id object, int code, const char* fmt, ...);
|
||||
extern void objc_verror(id object, int code, const char* fmt, va_list ap);
|
||||
typedef BOOL (*objc_error_handler)(id, int code, const char *fmt, va_list ap);
|
||||
objc_error_handler objc_set_error_handler(objc_error_handler func);
|
||||
|
||||
/*
|
||||
** Error codes
|
||||
** These are used by the runtime library, and your
|
||||
** error handling may use them to determine if the error is
|
||||
** hard or soft thus whether execution can continue or abort.
|
||||
*/
|
||||
#define OBJC_ERR_UNKNOWN 0 /* Generic error */
|
||||
|
||||
#define OBJC_ERR_OBJC_VERSION 1 /* Incorrect runtime version */
|
||||
#define OBJC_ERR_GCC_VERSION 2 /* Incorrect compiler version */
|
||||
#define OBJC_ERR_MODULE_SIZE 3 /* Bad module size */
|
||||
#define OBJC_ERR_PROTOCOL_VERSION 4 /* Incorrect protocol version */
|
||||
|
||||
#define OBJC_ERR_MEMORY 10 /* Out of memory */
|
||||
|
||||
#define OBJC_ERR_RECURSE_ROOT 20 /* Attempt to archive the root
|
||||
object more than once. */
|
||||
#define OBJC_ERR_BAD_DATA 21 /* Didn't read expected data */
|
||||
#define OBJC_ERR_BAD_KEY 22 /* Bad key for object */
|
||||
#define OBJC_ERR_BAD_CLASS 23 /* Unknown class */
|
||||
#define OBJC_ERR_BAD_TYPE 24 /* Bad type specification */
|
||||
#define OBJC_ERR_NO_READ 25 /* Cannot read stream */
|
||||
#define OBJC_ERR_NO_WRITE 26 /* Cannot write stream */
|
||||
#define OBJC_ERR_STREAM_VERSION 27 /* Incorrect stream version */
|
||||
#define OBJC_ERR_BAD_OPCODE 28 /* Bad opcode */
|
||||
|
||||
#define OBJC_ERR_UNIMPLEMENTED 30 /* Method is not implemented */
|
||||
|
||||
#define OBJC_ERR_BAD_STATE 40 /* Bad thread state */
|
||||
|
||||
#else /* NeXT_RUNTIME */
|
||||
|
||||
/*
|
||||
* And to use the GNU runtime from old NeXT code ...
|
||||
*/
|
||||
#define class_createInstance(CLASS, X) class_create_instance(CLASS)
|
||||
#define class_getInstanceMethod class_get_instance_method
|
||||
#define class_addMethods class_add_method_list
|
||||
#define class_setVersion class_set_version
|
||||
#define class_getVersion class_get_version
|
||||
#define class_poseAs class_pose_as
|
||||
#define method_getSizeOfArguments method_get_sizeof_arguments
|
||||
#define objc_lookUpClass objc_lookup_class
|
||||
#define objc_getClass objc_get_class
|
||||
|
||||
#define sel_registerName sel_register_name
|
||||
#define sel_isMapped sel_is_mapped
|
||||
#define sel_getName sel_get_name
|
||||
#define sel_getUid sel_get_any_uid
|
||||
|
||||
#define _objc_flush_caches __objc_update_dispatch_table_for_class
|
||||
|
||||
#define class_getClassMethod(CLASS, SEL) \
|
||||
class_get_class_method((CLASS)->class_pointer, (SEL))
|
||||
|
||||
#define class_nextMethodList(aClass,anIterator) (({\
|
||||
if (*(anIterator) == 0) \
|
||||
*((struct objc_method_list**)(anIterator)) = (aClass)->methods; \
|
||||
else \
|
||||
*(anIterator) = (*((struct objc_method_list**)(anIterator)))->method_next; \
|
||||
}), *(anIterator))
|
||||
|
||||
#endif /* NeXT_RUNTIME */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __objc_gnu2next_h_GNUSTEP_BASE_INCLUDE */
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <GNUstepBase/objc-gnu2next.h>
|
||||
|
||||
#if defined(__WIN32__) || defined(_WIN32) || defined(__MS_WIN32__)
|
||||
#ifndef __WIN32__
|
||||
|
|
|
@ -103,12 +103,6 @@ ifeq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd)
|
|||
OBJC_LIBS += -lpthread
|
||||
endif
|
||||
|
||||
ifneq ($(OBJC_RUNTIME_LIB), gnu)
|
||||
ifneq ($(OBJC_RUNTIME_LIB), gnugc)
|
||||
GNU_MFILES += objc-gnu2next.m
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(GNUSTEP_TARGET_OS), mingw32)
|
||||
GNU_MFILES += libgnustep-base-entry.m
|
||||
endif
|
||||
|
@ -142,7 +136,6 @@ Unicode.h \
|
|||
GNUstep.h \
|
||||
behavior.h \
|
||||
preface.h \
|
||||
objc-gnu2next.h \
|
||||
|
||||
GNU_HEADERS = $(ADD_HEADERS)
|
||||
|
||||
|
|
|
@ -546,7 +546,7 @@ static IMP gs_objc_msg_forward (SEL sel)
|
|||
_sig = RETAIN(aSignature);
|
||||
_numArgs = [aSignature numberOfArguments];
|
||||
_info = [aSignature methodInfo];
|
||||
_cframe = callframe_from_info(_info, _numArgs, &_retval);
|
||||
_cframe = callframe_from_signature(_sig, &_retval);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ static IMP gs_objc_msg_forward2 (id receiver, SEL sel)
|
|||
/* Note: We malloc 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], 0);
|
||||
cframe = cifframe_from_signature(sig);
|
||||
/* Autorelease the closure through GSAutoreleasedBuffer */
|
||||
|
||||
memory = [GSCodeBuffer memoryWithSize: sizeof(ffi_closure)];
|
||||
|
@ -312,7 +312,7 @@ static id gs_objc_proxy_lookup(id receiver, SEL op)
|
|||
_sig = RETAIN(aSignature);
|
||||
_numArgs = [aSignature numberOfArguments];
|
||||
_info = [aSignature methodInfo];
|
||||
_cframe = cifframe_from_info(_info, _numArgs, 0);
|
||||
_cframe = cifframe_from_signature(_sig);
|
||||
|
||||
/* Make sure we have somewhere to store the return value if needed.
|
||||
*/
|
||||
|
|
|
@ -66,7 +66,6 @@ static GC_descr nodeDesc; // Type descriptor for map node.
|
|||
#include "Foundation/NSConnection.h"
|
||||
#undef _IN_CONNECTION_M
|
||||
|
||||
#include <mframe.h>
|
||||
#if defined(USE_LIBFFI)
|
||||
#include "cifframe.h"
|
||||
#elif defined(USE_FFCALL)
|
||||
|
@ -1972,7 +1971,7 @@ static NSLock *cached_proxies_gate = nil;
|
|||
BOOL outParams;
|
||||
BOOL needsResponse;
|
||||
const char *type;
|
||||
DOContext ctxt;
|
||||
unsigned seq;
|
||||
NSRunLoop *runLoop = GSRunLoopForThread(nil);
|
||||
|
||||
if ([IrunLoops indexOfObjectIdenticalTo: runLoop] == NSNotFound)
|
||||
|
@ -2005,13 +2004,10 @@ static NSLock *cached_proxies_gate = nil;
|
|||
NSParameterAssert(type);
|
||||
NSParameterAssert(*type);
|
||||
|
||||
memset(&ctxt, 0, sizeof(ctxt));
|
||||
ctxt.connection = self;
|
||||
|
||||
op = [self _makeOutRmc: 0 generate: (int*)&ctxt.seq reply: YES];
|
||||
op = [self _makeOutRmc: 0 generate: (int*)&seq reply: YES];
|
||||
|
||||
if (debug_connection > 4)
|
||||
NSLog(@"building packet seq %d", ctxt.seq);
|
||||
NSLog(@"building packet seq %d", seq);
|
||||
|
||||
[inv setTarget: object];
|
||||
outParams = [inv encodeWithDistantCoder: op passPointers: NO];
|
||||
|
@ -2043,7 +2039,7 @@ static NSLock *cached_proxies_gate = nil;
|
|||
|
||||
[self _sendOutRmc: op type: METHOD_REQUEST];
|
||||
NSDebugMLLog(@"NSConnection", @"Sent message %s RMC %d to 0x%x",
|
||||
GSNameFromSelector([inv selector]), ctxt.seq, (uintptr_t)self);
|
||||
GSNameFromSelector([inv selector]), seq, (uintptr_t)self);
|
||||
|
||||
if (needsResponse == NO)
|
||||
{
|
||||
|
@ -2055,7 +2051,7 @@ static NSLock *cached_proxies_gate = nil;
|
|||
* a response, we must check for it and scrap it if necessary.
|
||||
*/
|
||||
M_LOCK(IrefGate);
|
||||
node = GSIMapNodeForKey(IreplyMap, (GSIMapKey)ctxt.seq);
|
||||
node = GSIMapNodeForKey(IreplyMap, (GSIMapKey)seq);
|
||||
if (node != 0 && node->value.obj != dummyObject)
|
||||
{
|
||||
BOOL is_exception = NO;
|
||||
|
@ -2069,7 +2065,7 @@ static NSLock *cached_proxies_gate = nil;
|
|||
NSLog(@"Got response with %@", NSStringFromSelector(sel));
|
||||
[self _doneInRmc: node->value.obj];
|
||||
}
|
||||
GSIMapRemoveKey(IreplyMap, (GSIMapKey)ctxt.seq);
|
||||
GSIMapRemoveKey(IreplyMap, (GSIMapKey)seq);
|
||||
M_UNLOCK(IrefGate);
|
||||
}
|
||||
else
|
||||
|
@ -2086,7 +2082,7 @@ static NSLock *cached_proxies_gate = nil;
|
|||
[NSException raise: NSGenericException
|
||||
format: @"connection waiting for request was shut down"];
|
||||
}
|
||||
aRmc = [self _getReplyRmc: ctxt.seq];
|
||||
aRmc = [self _getReplyRmc: seq];
|
||||
|
||||
/*
|
||||
* Find out if the server is returning an exception instead
|
||||
|
@ -2483,11 +2479,10 @@ static NSLock *cached_proxies_gate = nil;
|
|||
- (void) _service_forwardForProxy: (NSPortCoder*)aRmc
|
||||
{
|
||||
char *forward_type = 0;
|
||||
DOContext ctxt;
|
||||
|
||||
memset(&ctxt, 0, sizeof(ctxt));
|
||||
ctxt.connection = self;
|
||||
ctxt.decoder = aRmc;
|
||||
NSPortCoder *decoder = nil;
|
||||
NSPortCoder *encoder = nil;
|
||||
NSInvocation *inv = nil;
|
||||
unsigned seq;
|
||||
|
||||
/*
|
||||
* Make sure don't let exceptions caused by servicing the client's
|
||||
|
@ -2495,7 +2490,20 @@ static NSLock *cached_proxies_gate = nil;
|
|||
*/
|
||||
NS_DURING
|
||||
{
|
||||
NSRunLoop *runLoop = GSRunLoopForThread(nil);
|
||||
NSRunLoop *runLoop = GSRunLoopForThread(nil);
|
||||
const char *type;
|
||||
const char *tmptype;
|
||||
const char *etmptype;
|
||||
id tmp;
|
||||
id object;
|
||||
SEL selector;
|
||||
GSMethod meth = 0;
|
||||
BOOL is_exception = NO;
|
||||
unsigned flags;
|
||||
int argnum;
|
||||
BOOL out_parameters = NO;
|
||||
NSMethodSignature *sig;
|
||||
const char *encoded_types = forward_type;
|
||||
|
||||
NSParameterAssert (IisValid);
|
||||
if ([IrunLoops indexOfObjectIdenticalTo: runLoop] == NSNotFound)
|
||||
|
@ -2512,7 +2520,7 @@ static NSLock *cached_proxies_gate = nil;
|
|||
}
|
||||
|
||||
/* Save this for later */
|
||||
[aRmc decodeValueOfObjCType: @encode(int) at: &ctxt.seq];
|
||||
[aRmc decodeValueOfObjCType: @encode(int) at: &seq];
|
||||
|
||||
/*
|
||||
* Get the types that we're using, so that we know
|
||||
|
@ -2522,51 +2530,25 @@ static NSLock *cached_proxies_gate = nil;
|
|||
* to do this.
|
||||
*/
|
||||
[aRmc decodeValueOfObjCType: @encode(char*) at: &forward_type];
|
||||
ctxt.type = forward_type;
|
||||
|
||||
if (debug_connection > 1)
|
||||
NSLog(
|
||||
@"Handling message (sig %s) RMC %d from %@",
|
||||
ctxt.type, ctxt.seq, (uintptr_t)self);
|
||||
forward_type, seq, (uintptr_t)self);
|
||||
|
||||
IreqInCount++; /* Handling an incoming request. */
|
||||
{
|
||||
/* The method type string obtained from the target's OBJC_METHOD
|
||||
structure for the selector we're sending. */
|
||||
const char *type;
|
||||
/* A pointer into the local variable TYPE string. */
|
||||
const char *tmptype;
|
||||
/* A pointer into the argument ENCODED_TYPES string. */
|
||||
const char *etmptype;
|
||||
/* The target object that will receive the message. */
|
||||
id object;
|
||||
/* The selector for the message we're sending to the TARGET. */
|
||||
SEL selector;
|
||||
/* The OBJECT's Method(_t) pointer for the SELECTOR. */
|
||||
GSMethod meth = 0;
|
||||
BOOL is_exception = NO;
|
||||
/* Type qualifier flags; see <objc/objc-api.h>. */
|
||||
unsigned flags;
|
||||
/* Which argument number are we processing now? */
|
||||
int argnum;
|
||||
/* Does the method have any arguments that are passed by reference?
|
||||
If so, we need to encode them, since the method may have changed them. */
|
||||
BOOL out_parameters = NO;
|
||||
NSInvocation *inv;
|
||||
/* Signature information */
|
||||
NSMethodSignature *sig;
|
||||
const char *encoded_types = forward_type;
|
||||
|
||||
encoded_types = forward_type;
|
||||
etmptype = encoded_types;
|
||||
|
||||
ctxt.encoder = aRmc;
|
||||
decoder = aRmc;
|
||||
|
||||
/* Decode the object, (which is always the first argument to a method). */
|
||||
[aRmc decodeValueOfObjCType: @encode(id) at: &object];
|
||||
[decoder decodeValueOfObjCType: @encode(id) at: &object];
|
||||
|
||||
/* Decode the selector, (which is always the second argument to a method). */
|
||||
/* Decode the selector, (which is the second argument to a method). */
|
||||
/* xxx @encode(SEL) produces "^v" in gcc 2.5.8. It should be ":" */
|
||||
[aRmc decodeValueOfObjCType: @encode(SEL) at: &selector];
|
||||
[decoder decodeValueOfObjCType: @encode(SEL) at: &selector];
|
||||
|
||||
/* Get the "selector type" for this method. The "selector type" is
|
||||
a string that lists the return and argument types, and also
|
||||
|
@ -2617,7 +2599,6 @@ static NSLock *cached_proxies_gate = nil;
|
|||
|
||||
sig = [NSMethodSignature signatureWithObjCTypes: type];
|
||||
inv = [[NSInvocation alloc] initWithMethodSignature: sig];
|
||||
ctxt.objToFree = inv;
|
||||
|
||||
tmptype = objc_skip_argspec (type);
|
||||
etmptype = objc_skip_argspec (etmptype);
|
||||
|
@ -2674,7 +2655,7 @@ static NSLock *cached_proxies_gate = nil;
|
|||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
{
|
||||
datum = alloca (sizeof(char*));
|
||||
[aRmc decodeValueOfObjCType: tmptype at: datum];
|
||||
[decoder decodeValueOfObjCType: tmptype at: datum];
|
||||
[inv setArgument: datum atIndex: argnum];
|
||||
}
|
||||
break;
|
||||
|
@ -2699,7 +2680,7 @@ static NSLock *cached_proxies_gate = nil;
|
|||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
{
|
||||
datum = alloca (objc_sizeof_type (tmptype));
|
||||
[aRmc decodeValueOfObjCType: tmptype at: datum];
|
||||
[decoder decodeValueOfObjCType: tmptype at: datum];
|
||||
[inv setArgument: &datum atIndex: argnum];
|
||||
}
|
||||
break;
|
||||
|
@ -2708,11 +2689,11 @@ static NSLock *cached_proxies_gate = nil;
|
|||
datum = alloca (objc_sizeof_type (tmptype));
|
||||
if (*tmptype == _C_ID)
|
||||
{
|
||||
*(id*)datum = [aRmc decodeObject];
|
||||
*(id*)datum = [decoder decodeObject];
|
||||
}
|
||||
else
|
||||
{
|
||||
[aRmc decodeValueOfObjCType: tmptype at: datum];
|
||||
[decoder decodeValueOfObjCType: tmptype at: datum];
|
||||
}
|
||||
[inv setArgument: datum atIndex: argnum];
|
||||
}
|
||||
|
@ -2720,8 +2701,9 @@ static NSLock *cached_proxies_gate = nil;
|
|||
|
||||
/* Stop using the decoder.
|
||||
*/
|
||||
[self _doneInRmc: aRmc];
|
||||
ctxt.decoder = nil;
|
||||
tmp = decoder;
|
||||
decoder = nil;
|
||||
[self _doneInRmc: tmp];
|
||||
|
||||
/* Invoke the method! */
|
||||
[inv invoke];
|
||||
|
@ -2732,6 +2714,9 @@ static NSLock *cached_proxies_gate = nil;
|
|||
*/
|
||||
if ([self isValid] == NO)
|
||||
{
|
||||
tmp = inv;
|
||||
inv = nil;
|
||||
[tmp release];
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2739,9 +2724,8 @@ static NSLock *cached_proxies_gate = nil;
|
|||
* later use if/when we are called again. We encode a flag to
|
||||
* say that this is not an exception.
|
||||
*/
|
||||
aRmc = [self _makeOutRmc: ctxt.seq generate: 0 reply: NO];
|
||||
ctxt.encoder = aRmc;
|
||||
[aRmc encodeValueOfObjCType: @encode(BOOL) at: &is_exception];
|
||||
encoder = [self _makeOutRmc: seq generate: 0 reply: NO];
|
||||
[encoder encodeValueOfObjCType: @encode(BOOL) at: &is_exception];
|
||||
|
||||
/* Encode the return value and pass-by-reference values, if there
|
||||
are any. This logic must match exactly that in
|
||||
|
@ -2765,7 +2749,7 @@ static NSLock *cached_proxies_gate = nil;
|
|||
{
|
||||
int dummy = 0;
|
||||
|
||||
[aRmc encodeValueOfObjCType: @encode(int) at: (void*)&dummy];
|
||||
[encoder encodeValueOfObjCType: @encode(int) at: (void*)&dummy];
|
||||
}
|
||||
/* No return value to encode; do nothing. */
|
||||
}
|
||||
|
@ -2785,7 +2769,7 @@ static NSLock *cached_proxies_gate = nil;
|
|||
datum = alloca (objc_sizeof_type (tmptype));
|
||||
}
|
||||
[inv getReturnValue: datum];
|
||||
[aRmc encodeValueOfObjCType: tmptype at: datum];
|
||||
[encoder encodeValueOfObjCType: tmptype at: datum];
|
||||
}
|
||||
|
||||
|
||||
|
@ -2827,22 +2811,23 @@ static NSLock *cached_proxies_gate = nil;
|
|||
it is a pass-by-reference argument.*/
|
||||
++tmptype;
|
||||
[inv getArgument: &datum atIndex: argnum];
|
||||
[aRmc encodeValueOfObjCType: tmptype at: datum];
|
||||
[encoder encodeValueOfObjCType: tmptype at: datum];
|
||||
}
|
||||
else if (*tmptype == _C_CHARPTR)
|
||||
{
|
||||
datum = alloca (sizeof (char*));
|
||||
[inv getArgument: datum atIndex: argnum];
|
||||
[aRmc encodeValueOfObjCType: tmptype at: datum];
|
||||
[encoder encodeValueOfObjCType: tmptype at: datum];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ctxt.objToFree = nil;
|
||||
[inv release];
|
||||
[self _sendOutRmc: aRmc type: METHOD_REPLY];
|
||||
ctxt.encoder = nil;
|
||||
}
|
||||
tmp = inv;
|
||||
inv = nil;
|
||||
[tmp release];
|
||||
tmp = encoder;
|
||||
encoder = nil;
|
||||
[self _sendOutRmc: tmp type: METHOD_REPLY];
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
|
@ -2858,25 +2843,19 @@ static NSLock *cached_proxies_gate = nil;
|
|||
{
|
||||
NSPortCoder *op;
|
||||
|
||||
if (ctxt.datToFree != 0)
|
||||
if (inv != nil)
|
||||
{
|
||||
NSZoneFree(NSDefaultMallocZone(), ctxt.datToFree);
|
||||
ctxt.datToFree = 0;
|
||||
[inv release];
|
||||
}
|
||||
if (ctxt.objToFree != nil)
|
||||
if (decoder != nil)
|
||||
{
|
||||
NSDeallocateObject(ctxt.objToFree);
|
||||
ctxt.objToFree = nil;
|
||||
[self _failInRmc: decoder];
|
||||
}
|
||||
if (ctxt.decoder != nil)
|
||||
if (encoder != nil)
|
||||
{
|
||||
[self _failInRmc: ctxt.decoder];
|
||||
[self _failOutRmc: encoder];
|
||||
}
|
||||
if (ctxt.encoder != nil)
|
||||
{
|
||||
[self _failOutRmc: ctxt.encoder];
|
||||
}
|
||||
op = [self _makeOutRmc: ctxt.seq generate: 0 reply: NO];
|
||||
op = [self _makeOutRmc: seq generate: 0 reply: NO];
|
||||
[op encodeValueOfObjCType: @encode(BOOL)
|
||||
at: &is_exception];
|
||||
[op encodeBycopyObject: localException];
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "GSInvocation.h"
|
||||
#include "config.h"
|
||||
#include "GSPrivate.h"
|
||||
#include <mframe.h>
|
||||
#if defined(USE_LIBFFI)
|
||||
#include "cifframe.h"
|
||||
#elif defined(USE_FFCALL)
|
||||
|
@ -228,22 +227,21 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void
|
||||
_get_arg(NSInvocation *inv, int index, void *buffer)
|
||||
{
|
||||
mframe_get_arg((arglist_t)inv->_cframe, &inv->_info[index+1], buffer);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_set_arg(NSInvocation *inv, int index, void *buffer)
|
||||
{
|
||||
mframe_set_arg((arglist_t)inv->_cframe, &inv->_info[index+1], buffer);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
_arg_addr(NSInvocation *inv, int index)
|
||||
{
|
||||
return mframe_arg_addr((arglist_t)inv->_cframe, &inv->_info[index+1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -270,7 +268,7 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
#elif defined(USE_FFCALL)
|
||||
NSInvocation_concrete_class = [GSFFCallInvocation class];
|
||||
#else
|
||||
NSInvocation_concrete_class = [GSFrameInvocation class];
|
||||
NSInvocation_concrete_class = [GSDummyInvocation class];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -306,14 +304,17 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
{
|
||||
if (*_info[i].type == _C_CHARPTR)
|
||||
{
|
||||
char *str;
|
||||
char *str = 0;
|
||||
|
||||
_get_arg(self, i-1, &str);
|
||||
NSZoneFree(NSDefaultMallocZone(), str);
|
||||
if (str != 0)
|
||||
{
|
||||
NSZoneFree(NSDefaultMallocZone(), str);
|
||||
}
|
||||
}
|
||||
else if (*_info[i].type == _C_ID)
|
||||
{
|
||||
id obj;
|
||||
id obj = nil;
|
||||
|
||||
_get_arg(self, i-1, &obj);
|
||||
RELEASE(obj);
|
||||
|
@ -335,15 +336,6 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
{
|
||||
NSZoneFree(NSDefaultMallocZone(), _cframe);
|
||||
}
|
||||
#else
|
||||
if (_cframe)
|
||||
{
|
||||
mframe_destroy_argframe([_sig methodType], (arglist_t)_cframe);
|
||||
}
|
||||
if (_retval)
|
||||
{
|
||||
NSZoneFree(NSDefaultMallocZone(), _retval);
|
||||
}
|
||||
#endif
|
||||
if (_retptr)
|
||||
{
|
||||
|
@ -400,17 +392,7 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
|
||||
if (*_info[0].type != _C_VOID)
|
||||
{
|
||||
int length = _info[0].size;
|
||||
#if !defined(USE_LIBFFI) && !defined(USE_FFCALL)
|
||||
/* NOTE: This won't work unless -[NSMethodSignature methodReturnLength]
|
||||
is also changed, but since mframe is depreciated, this should all
|
||||
be removed in the near future anyway... */
|
||||
#if WORDS_BIGENDIAN
|
||||
if (length < sizeof(void*))
|
||||
length = sizeof(void*);
|
||||
#endif
|
||||
#endif
|
||||
memcpy(buffer, _retval, length);
|
||||
memcpy(buffer, _retval, _info[0].size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -512,18 +494,7 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
|
||||
if (*type != _C_VOID)
|
||||
{
|
||||
int length = _info[0].size;
|
||||
|
||||
#if !defined(USE_LIBFFI) && !defined(USE_FFCALL)
|
||||
/* NOTE: This won't work unless -[NSMethodSignature methodReturnLength]
|
||||
is also changed, but since mframe is depreciated, this should all
|
||||
be removed in the near future anyway... */
|
||||
#if WORDS_BIGENDIAN
|
||||
if (length < sizeof(void*))
|
||||
length = sizeof(void*);
|
||||
#endif
|
||||
#endif
|
||||
memcpy(_retval, buffer, length);
|
||||
memcpy(_retval, buffer, _info[0].size);
|
||||
}
|
||||
|
||||
RETAIN_RETURN_VALUE;
|
||||
|
@ -678,7 +649,7 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
GSClassNameFromObject(self), \
|
||||
self, \
|
||||
_selector ? GSNameFromSelector(_selector) : "nil", \
|
||||
_target ? GSNameFromClass([_target class]) : "nil" \
|
||||
_target ? GSNameFromClass([_target class]) : "nil" \
|
||||
);
|
||||
|
||||
return [NSString stringWithUTF8String: buffer];
|
||||
|
@ -708,14 +679,6 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
{
|
||||
[aCoder encodeObject: *(id*)datum];
|
||||
}
|
||||
#if !defined(USE_LIBFFI) && !defined(USE_FFCALL)
|
||||
#if MFRAME_STRUCT_BYREF
|
||||
else if (*type == _C_STRUCT_B || *type == _C_UNION_B || *type == _C_ARY_B)
|
||||
{
|
||||
[aCoder encodeValueOfObjCType: type at: *(void**)datum];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
else
|
||||
{
|
||||
[aCoder encodeValueOfObjCType: type at: datum];
|
||||
|
@ -752,18 +715,6 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
for (i = 3; i <= _numArgs; i++)
|
||||
{
|
||||
datum = _arg_addr(self, i-1);
|
||||
#if !defined(USE_LIBFFI) && !defined(USE_FFCALL)
|
||||
#if MFRAME_STRUCT_BYREF
|
||||
{
|
||||
const char *t = _info[i].type;
|
||||
if (*t == _C_STRUCT_B || *t == _C_UNION_B || *t == _C_ARY_B)
|
||||
{
|
||||
*(void**)datum = GSAutoreleasedBuffer(_info[i].size);
|
||||
datum = *(void**)datum;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
[aCoder decodeValueOfObjCType: _info[i].type at: datum];
|
||||
}
|
||||
_argsRetained = YES;
|
||||
|
@ -894,29 +845,11 @@ _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
|
||||
#warning Using dummy NSInvocation implementation. It is strongly recommended that you use libffi.
|
||||
@implementation GSDummyInvocation
|
||||
|
||||
- (id) initWithArgframe: (arglist_t)frame selector: (SEL)aSelector
|
||||
{
|
||||
self = [self initWithSelector: aSelector];
|
||||
if (self)
|
||||
{
|
||||
[self setSelector: aSelector];
|
||||
/*
|
||||
* Copy the _cframe we were given.
|
||||
*/
|
||||
if (frame)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
mframe_get_arg(frame, &_info[1], &_target);
|
||||
for (i = 1; i <= _numArgs; i++)
|
||||
{
|
||||
mframe_cpy_arg((arglist_t)_cframe, frame, &_info[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -925,104 +858,26 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
*/
|
||||
- (id) initWithMethodSignature: (NSMethodSignature*)aSignature
|
||||
{
|
||||
if (aSignature == nil)
|
||||
{
|
||||
RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
_sig = RETAIN(aSignature);
|
||||
_numArgs = [aSignature numberOfArguments];
|
||||
_info = [aSignature methodInfo];
|
||||
_cframe = mframe_create_argframe([_sig methodType], &_retval);
|
||||
if (_retval == 0 && _info[0].size > 0)
|
||||
{
|
||||
_retval = NSZoneMalloc(NSDefaultMallocZone(), _info[0].size);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (void)invokeWithTarget: (id)anObject
|
||||
|
||||
- (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);
|
||||
return 0;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)other
|
||||
- (BOOL) isEqual: (id)other
|
||||
{
|
||||
BOOL isEqual = YES;
|
||||
if (other == nil)
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "Foundation/NSException.h"
|
||||
#include "Foundation/NSObjCRuntime.h"
|
||||
#include "Foundation/NSString.h"
|
||||
#include <mframe.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
|
@ -140,12 +139,12 @@ NSStringFromClass(Class aClass)
|
|||
const char *
|
||||
NSGetSizeAndAlignment(const char *typePtr, unsigned *sizep, unsigned *alignp)
|
||||
{
|
||||
NSArgumentInfo info;
|
||||
typePtr = mframe_next_arg(typePtr, &info, 0);
|
||||
typePtr = objc_skip_offset (typePtr);
|
||||
typePtr = objc_skip_type_qualifiers (typePtr);
|
||||
if (sizep)
|
||||
*sizep = info.size;
|
||||
*sizep = objc_sizeof_type (typePtr);
|
||||
if (alignp)
|
||||
*alignp = info.align;
|
||||
*alignp = objc_alignof_type (typePtr);
|
||||
return typePtr;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ typedef struct _callframe_t {
|
|||
void **args;
|
||||
} callframe_t;
|
||||
|
||||
extern callframe_t *callframe_from_info (NSArgumentInfo *info, int numargs,
|
||||
void **retval);
|
||||
extern callframe_t *callframe_from_signature (NSMethodSignature *info,
|
||||
void **retval);
|
||||
extern void callframe_set_arg(callframe_t *cframe, int index, void *buffer,
|
||||
int size);
|
||||
extern void callframe_get_arg(callframe_t *cframe, int index, void *buffer,
|
||||
|
|
|
@ -42,11 +42,12 @@ typedef int smallret_t;
|
|||
#endif
|
||||
|
||||
callframe_t *
|
||||
callframe_from_info (NSArgumentInfo *info, int numargs, void **retval)
|
||||
callframe_from_signature (NSMethodSignature *info, void **retval)
|
||||
{
|
||||
unsigned size = sizeof(callframe_t);
|
||||
unsigned align = __alignof(double);
|
||||
unsigned offset = 0;
|
||||
unsigned numargs = [info numberOfArguments];
|
||||
void *buf;
|
||||
int i;
|
||||
callframe_t *cframe;
|
||||
|
@ -65,8 +66,9 @@ callframe_from_info (NSArgumentInfo *info, int numargs, void **retval)
|
|||
}
|
||||
for (i = 0; i < numargs; i++)
|
||||
{
|
||||
size += info[i+1].size;
|
||||
const char *type = [info getArgumentTypeAtIndex: i];
|
||||
|
||||
size += objc_sizeof_type (type);
|
||||
if (size % align != 0)
|
||||
{
|
||||
size += (align - size % align);
|
||||
|
@ -81,15 +83,26 @@ callframe_from_info (NSArgumentInfo *info, int numargs, void **retval)
|
|||
*/
|
||||
if (retval)
|
||||
{
|
||||
unsigned full = size;
|
||||
unsigned pos;
|
||||
const char *type = [info methodReturnType];
|
||||
unsigned full = size;
|
||||
unsigned pos;
|
||||
unsigned ret;
|
||||
|
||||
if (full % align != 0)
|
||||
{
|
||||
full += (align - full % align);
|
||||
}
|
||||
if (full % 8 != 0)
|
||||
{
|
||||
full += (8 - full % 8);
|
||||
}
|
||||
pos = full;
|
||||
full += MAX(info[0].size, sizeof(smallret_t));
|
||||
ret = MAX(objc_sizeof_type (type), sizeof(double));
|
||||
/* The addition of a constant '8' is a fudge applied simply because
|
||||
* some return values write beynd the end of the memory if the buffer
|
||||
* is sized exactly ... don't know why.
|
||||
*/
|
||||
full += ret + 8;
|
||||
#if GS_WITH_GC
|
||||
cframe = buf = NSAllocateCollectable(full, NSScannedOption);
|
||||
#else
|
||||
|
@ -122,7 +135,7 @@ callframe_from_info (NSArgumentInfo *info, int numargs, void **retval)
|
|||
{
|
||||
cframe->args[i] = buf + offset;
|
||||
|
||||
offset += info[i+1].size;
|
||||
offset += objc_sizeof_type ([info getArgumentTypeAtIndex: i]);
|
||||
|
||||
if (offset % align != 0)
|
||||
{
|
||||
|
|
|
@ -50,8 +50,7 @@ typedef struct _cifframe_t {
|
|||
void **values;
|
||||
} cifframe_t;
|
||||
|
||||
extern cifframe_t *cifframe_from_info (NSArgumentInfo *info, int numargs,
|
||||
void **retval);
|
||||
extern cifframe_t *cifframe_from_signature (NSMethodSignature *info);
|
||||
|
||||
extern void cifframe_set_arg(cifframe_t *cframe, int index, void *buffer,
|
||||
int size);
|
||||
|
|
|
@ -121,7 +121,7 @@ cifframe_guess_struct_size(ffi_type *stype)
|
|||
|
||||
|
||||
cifframe_t *
|
||||
cifframe_from_info (NSArgumentInfo *info, int numargs, void **retval)
|
||||
cifframe_from_signature (NSMethodSignature *info)
|
||||
{
|
||||
unsigned size = sizeof(cifframe_t);
|
||||
unsigned align = __alignof(double);
|
||||
|
@ -129,6 +129,7 @@ cifframe_from_info (NSArgumentInfo *info, int numargs, void **retval)
|
|||
unsigned offset = 0;
|
||||
void *buf;
|
||||
int i;
|
||||
int numargs = [info numberOfArguments];
|
||||
ffi_type *rtype;
|
||||
ffi_type *arg_types[numargs];
|
||||
cifframe_t *cframe;
|
||||
|
@ -137,10 +138,10 @@ cifframe_from_info (NSArgumentInfo *info, int numargs, void **retval)
|
|||
have custom ffi_types with are allocated separately. We should allocate
|
||||
them in our cifframe so we don't leak memory. Or maybe we could
|
||||
cache structure types? */
|
||||
rtype = cifframe_type(info[0].type, NULL);
|
||||
rtype = cifframe_type([info methodReturnType], NULL);
|
||||
for (i = 0; i < numargs; i++)
|
||||
{
|
||||
arg_types[i] = cifframe_type(info[i+1].type, NULL);
|
||||
arg_types[i] = cifframe_type([info getArgumentTypeAtIndex: i], NULL);
|
||||
}
|
||||
|
||||
if (numargs > 0)
|
||||
|
@ -176,48 +177,11 @@ cifframe_from_info (NSArgumentInfo *info, int numargs, void **retval)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we need space allocated to store a return value,
|
||||
* make room for it at the end of the cifframe so we
|
||||
* only need to do a single malloc.
|
||||
*/
|
||||
if (rtype && (rtype->size > 0 || rtype->elements != NULL))
|
||||
{
|
||||
unsigned full = size;
|
||||
unsigned pos;
|
||||
|
||||
if (full % align != 0)
|
||||
{
|
||||
full += (align - full % align);
|
||||
}
|
||||
pos = full;
|
||||
if (rtype->elements)
|
||||
full += cifframe_guess_struct_size(rtype);
|
||||
else
|
||||
full += MAX(rtype->size, sizeof(smallret_t));
|
||||
/* HACK ... not sure why, but on my 64bit intel system adding a bit
|
||||
* more to the buffer size prevents writing outside the allocated
|
||||
* memory by the ffi stuff.
|
||||
*/
|
||||
full += 64;
|
||||
#if GS_WITH_GC
|
||||
cframe = buf = NSAllocateCollectable(full, NSScannedOption);
|
||||
cframe = buf = NSAllocateCollectable(size, NSScannedOption);
|
||||
#else
|
||||
cframe = buf = NSZoneCalloc(NSDefaultMallocZone(), full, 1);
|
||||
cframe = buf = NSZoneCalloc(NSDefaultMallocZone(), size, 1);
|
||||
#endif
|
||||
if (cframe && retval)
|
||||
{
|
||||
*retval = buf + pos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
cframe = buf = NSAllocateCollectable(size, NSScannedOption);
|
||||
#else
|
||||
cframe = buf = NSZoneCalloc(NSDefaultMallocZone(), size, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (cframe)
|
||||
{
|
||||
|
|
1240
Source/mframe.m
1240
Source/mframe.m
File diff suppressed because it is too large
Load diff
|
@ -43,56 +43,6 @@ typedef union {
|
|||
} *arglist_t;
|
||||
#endif
|
||||
|
||||
/* These functions are used to pull apart method calls, and put them
|
||||
back together again. They are useful for things like distributed
|
||||
objects, and cross-language communication glue between Objective C
|
||||
and other languages. */
|
||||
|
||||
/* xxx Currently these function only work with the GNU Objective C
|
||||
runtime, not the NeXT runtime. */
|
||||
|
||||
|
||||
/* Extract the arguments to a method call, as found in ARGFRAME,
|
||||
according to type string TYPES, and encode them by calling ENCODER.
|
||||
Return YES if and only if the method has some pass-by-reference
|
||||
arguments. */
|
||||
|
||||
BOOL
|
||||
mframe_dissect_call (arglist_t argframe, const char *types,
|
||||
void (*encoder)(DOContext*), DOContext *ctxt);
|
||||
|
||||
/* Decode the arguments to a method call by calling DECODER, knowing
|
||||
what to decode by looking at type string ENCODED_TYPES. Build an
|
||||
argframe of type arglist_t, and invoke the method. Then encode the
|
||||
return value and the pass-by-reference values using ENCODER. */
|
||||
|
||||
void
|
||||
mframe_do_call (DOContext *ctxt,
|
||||
void(*decoder)(DOContext*),
|
||||
void(*encoder)(DOContext*));
|
||||
|
||||
/* Decode the return value and pass-by-reference arguments using
|
||||
DECODER, knowning what to decode by looking at type string TYPES
|
||||
and OUT_PARAMETERS, and put then into ARGFRAME. Return the
|
||||
retval_t structure that can be passed to __builtin_return(). */
|
||||
|
||||
retval_t
|
||||
mframe_build_return (arglist_t argframe, const char *types,
|
||||
BOOL out_parameters,
|
||||
void(*decoder)(DOContext*), DOContext *ctxt);
|
||||
|
||||
/*
|
||||
* Copy the return value from retframe into the specified buffer.
|
||||
*/
|
||||
BOOL
|
||||
mframe_decode_return(const char *type, void* buffer, void* retframe);
|
||||
|
||||
/*
|
||||
* Return the value of the specified type in 'retval' using argFrame.
|
||||
*/
|
||||
void*
|
||||
mframe_handle_return(const char* type, void* retval, arglist_t argFrame);
|
||||
|
||||
/*
|
||||
* Step through method encoding information extracting details.
|
||||
*/
|
||||
|
@ -108,21 +58,8 @@ char*
|
|||
mframe_build_signature(const char *typePtr, int *size, int *narg, char *buf);
|
||||
|
||||
|
||||
arglist_t
|
||||
mframe_create_argframe(const char *types, void** retbuf);
|
||||
|
||||
void
|
||||
mframe_destroy_argframe(const char *types, arglist_t argframe);
|
||||
|
||||
#define ROUND(V, A) \
|
||||
({ typeof(V) __v=(V); typeof(A) __a=(A); \
|
||||
__a*((__v+__a-1)/__a); })
|
||||
|
||||
|
||||
int method_types_get_sizeof_arguments (struct objc_method* mth);
|
||||
char* method_types_get_next_argument (arglist_t argf, const char **type);
|
||||
char* method_types_get_first_argument (struct objc_method* m,
|
||||
arglist_t argframe,
|
||||
const char** type);
|
||||
|
||||
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
/* Implementation to allow compilation of GNU objc code with NeXT runtime
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Author: Kresten Krab Thorup
|
||||
Modified by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: Sep 1994
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include "GNUstepBase/preface.h"
|
||||
#include "mframe.h"
|
||||
|
||||
id next_objc_msg_sendv(id object, SEL op, void* frame)
|
||||
{
|
||||
arglist_t argFrame = __builtin_apply_args();
|
||||
struct objc_method *m = class_get_instance_method(object->class_pointer, op);
|
||||
const char *type;
|
||||
void *result;
|
||||
|
||||
argFrame->arg_ptr = frame;
|
||||
*((id*)method_types_get_first_argument (m, argFrame, &type)) = object;
|
||||
*((SEL*)method_types_get_next_argument (argFrame, &type)) = op;
|
||||
result = __builtin_apply((apply_t)m->method_imp,
|
||||
argFrame,
|
||||
method_get_sizeof_arguments (m));
|
||||
|
||||
#if !defined(BROKEN_BUILTIN_APPLY) && defined(i386)
|
||||
/* Special hack to avoid pushing the poped float value back to the fp
|
||||
stack on i386 machines. This happens with NeXT runtime and 2.7.2
|
||||
compiler. If the result value is floating point don't call
|
||||
__builtin_return anymore. */
|
||||
if (*m->method_types == _C_FLT || *m->method_types == _C_DBL) {
|
||||
long double value = *(long double*)(((char*)result) + 8);
|
||||
asm("fld %0" : : "f" (value));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
__builtin_return(result);
|
||||
}
|
Loading…
Reference in a new issue