mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Fixes from Frith-MacDonald.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2794 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
80e0823d87
commit
c51efbe1e1
5 changed files with 550 additions and 72 deletions
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
|||
Mon Apr 27 15:45:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* src/include/mframe.h: Added three new functions to enable passing
|
||||
of pointers using the mframe routines.
|
||||
|
||||
* src/mframe.m: Added mframe_dissect_call_opts(),
|
||||
mframe_do_call_opts(), and mframe_build_return_opts() so that we
|
||||
may pass pointers to and from functions in other languages rather
|
||||
than using the DO behaviour which is to copy a single object when
|
||||
given a pointer.
|
||||
|
||||
Tue Apr 21 15:45:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* src/NSMethodSignature.m: ([+signatureWithObjCTypes:]) rewritten
|
||||
to use some macros from libFoundation (adapted from gcc) to handle
|
||||
creation of NSMethodSignature objects where the types string passed
|
||||
in does not contain the position information of the arguments.
|
||||
|
||||
Thu Apr 16 13:45:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* checks/client.m: enable testing of DO strucuture return.
|
||||
|
|
|
@ -14,6 +14,8 @@ help is greatly appreciated. Send email to
|
|||
|
||||
@itemize @bullet
|
||||
|
||||
@item Fix all the places marked FIXME or xxx.
|
||||
|
||||
@item Need to improve the testsuite and actually run it on gstep-base.
|
||||
|
||||
@item Change all the assert()'s (especially in the archiving code) to
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
BOOL
|
||||
mframe_dissect_call (arglist_t argframe, const char *types,
|
||||
void (*encoder)(int,void*,const char*,int));
|
||||
BOOL
|
||||
mframe_dissect_call_opts (arglist_t argframe, const char *types,
|
||||
void (*encoder)(int,void*,const char*,int),
|
||||
BOOL pass_pointers);
|
||||
|
||||
/* Decode the arguments to a method call by calling DECODER, knowing
|
||||
what to decode by looking at type string ENCODED_TYPES. Build an
|
||||
|
@ -53,6 +57,11 @@ void
|
|||
mframe_do_call (const char *encoded_types,
|
||||
void(*decoder)(int,void*,const char*),
|
||||
void(*encoder)(int,void*,const char*,int));
|
||||
void
|
||||
mframe_do_call_opts (const char *encoded_types,
|
||||
void(*decoder)(int,void*,const char*),
|
||||
void(*encoder)(int,void*,const char*,int),
|
||||
BOOL pass_pointers);
|
||||
|
||||
/* Decode the return value and pass-by-reference arguments using
|
||||
DECODER, knowning what to decode by looking at type string TYPES
|
||||
|
@ -63,5 +72,10 @@ retval_t
|
|||
mframe_build_return (arglist_t argframe, const char *types,
|
||||
BOOL out_parameters,
|
||||
void(*decoder)(int,void*,const char*,int));
|
||||
retval_t
|
||||
mframe_build_return_opts (arglist_t argframe, const char *types,
|
||||
BOOL out_parameters,
|
||||
void(*decoder)(int,void*,const char*,int),
|
||||
BOOL pass_pointers);
|
||||
|
||||
#endif /* __mframe_h_GNUSTEP_BASE_INCLUDE */
|
||||
|
|
|
@ -43,6 +43,371 @@
|
|||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSString.h>
|
||||
|
||||
|
||||
/*
|
||||
* These macros incorporated from libFoundation by R. Frith-Macdonald
|
||||
* are subject to the following copyright rather than the LGPL -
|
||||
*
|
||||
* Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
|
||||
*
|
||||
* This file is part of libFoundation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation.
|
||||
*
|
||||
* We disclaim all warranties with regard to this software, including all
|
||||
* implied warranties of merchantability and fitness, in no event shall
|
||||
* we be liable for any special, indirect or consequential damages or any
|
||||
* damages whatsoever resulting from loss of use, data or profits, whether in
|
||||
* an action of contract, negligence or other tortious action, arising out of
|
||||
* or in connection with the use or performance of this software.
|
||||
*/
|
||||
|
||||
#ifndef ROUND
|
||||
#define ROUND(V, A) \
|
||||
({ typeof(V) __v=(V); typeof(A) __a=(A); \
|
||||
__a*((__v+__a-1)/__a); })
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(alpha) && defined(linux)
|
||||
|
||||
#ifndef OBJC_FORWARDING_STACK_OFFSET
|
||||
#define OBJC_FORWARDING_STACK_OFFSET 0
|
||||
#endif
|
||||
|
||||
#ifndef OBJC_FORWARDING_MIN_OFFSET
|
||||
#define OBJC_FORWARDING_MIN_OFFSET 0
|
||||
#endif
|
||||
|
||||
#define CUMULATIVE_ARGS int
|
||||
|
||||
#define INIT_CUMULATIVE_ARGS(CUM) ((CUM) = 0)
|
||||
|
||||
#define FUNCTION_ARG_ENCODING(CUM, TYPE, STACK_ARGSIZE) \
|
||||
({ id encoding; \
|
||||
const char* type = [(TYPE) cString]; \
|
||||
int align = objc_alignof_type(type); \
|
||||
int type_size = objc_sizeof_type(type); \
|
||||
\
|
||||
(CUM) = ROUND((CUM), align); \
|
||||
encoding = [NSString stringWithFormat:@"%@%d", \
|
||||
(TYPE), \
|
||||
(CUM) + OBJC_FORWARDING_STACK_OFFSET]; \
|
||||
(STACK_ARGSIZE) = (CUM) + type_size; \
|
||||
(CUM) += ROUND(type_size, sizeof(void*)); \
|
||||
encoding; })
|
||||
|
||||
|
||||
#endif /* i386 linux */
|
||||
|
||||
#if defined(hppa)
|
||||
|
||||
#ifndef OBJC_FORWARDING_STACK_OFFSET
|
||||
#define OBJC_FORWARDING_STACK_OFFSET 0
|
||||
#endif
|
||||
|
||||
#ifndef OBJC_FORWARDING_MIN_OFFSET
|
||||
#define OBJC_FORWARDING_MIN_OFFSET 0
|
||||
#endif
|
||||
|
||||
#define CUMULATIVE_ARGS int
|
||||
|
||||
#define INIT_CUMULATIVE_ARGS(CUM) ((CUM) = 0)
|
||||
|
||||
#define FUNCTION_ARG_SIZE(TYPESIZE) \
|
||||
((TYPESIZE + 3) / 4)
|
||||
|
||||
#define FUNCTION_ARG_ENCODING(CUM, TYPE, STACK_ARGSIZE) \
|
||||
({ id encoding; \
|
||||
int align = objc_alignof_type([(TYPE) cString]); \
|
||||
int type_size = objc_sizeof_type([(TYPE) cString]); \
|
||||
const char* type = [(TYPE) cString]; \
|
||||
\
|
||||
(CUM) = ROUND((CUM), align); \
|
||||
encoding = [NSString stringWithFormat:@"%@%d", \
|
||||
(TYPE), \
|
||||
(CUM) + OBJC_FORWARDING_STACK_OFFSET]; \
|
||||
if((*type == _C_STRUCT_B || *type == _C_UNION_B || *type == _C_ARY_B)) \
|
||||
(STACK_ARGSIZE) = (CUM) + ROUND(type_size, align); \
|
||||
else (STACK_ARGSIZE) = (CUM) + type_size; \
|
||||
\
|
||||
/* Compute the new value of cumulative args */ \
|
||||
((((CUM) & 01) && FUNCTION_ARG_SIZE(type_size) > 1) && (CUM)++); \
|
||||
(CUM) += FUNCTION_ARG_SIZE(type_size); \
|
||||
encoding; })
|
||||
|
||||
#endif /* hppa */
|
||||
|
||||
#if defined(i386) && defined(linux)
|
||||
|
||||
#ifndef OBJC_FORWARDING_STACK_OFFSET
|
||||
#define OBJC_FORWARDING_STACK_OFFSET 0
|
||||
#endif
|
||||
|
||||
#ifndef OBJC_FORWARDING_MIN_OFFSET
|
||||
#define OBJC_FORWARDING_MIN_OFFSET 0
|
||||
#endif
|
||||
|
||||
#define CUMULATIVE_ARGS int
|
||||
|
||||
#define INIT_CUMULATIVE_ARGS(CUM) ((CUM) = 0)
|
||||
|
||||
#define FUNCTION_ARG_ENCODING(CUM, TYPE, STACK_ARGSIZE) \
|
||||
({ id encoding; \
|
||||
const char* type = [(TYPE) cString]; \
|
||||
int align = objc_alignof_type(type); \
|
||||
int type_size = objc_sizeof_type(type); \
|
||||
\
|
||||
(CUM) = ROUND((CUM), align); \
|
||||
encoding = [NSString stringWithFormat:@"%@%d", \
|
||||
(TYPE), \
|
||||
(CUM) + OBJC_FORWARDING_STACK_OFFSET]; \
|
||||
if((*type == _C_STRUCT_B || *type == _C_UNION_B || *type == _C_ARY_B) \
|
||||
&& type_size > 2) \
|
||||
(STACK_ARGSIZE) = (CUM) + ROUND(type_size, align); \
|
||||
else (STACK_ARGSIZE) = (CUM) + type_size; \
|
||||
(CUM) += ROUND(type_size, sizeof(void*)); \
|
||||
encoding; })
|
||||
|
||||
#endif /* i386 linux */
|
||||
|
||||
#if defined(m68k)
|
||||
|
||||
#ifndef OBJC_FORWARDING_STACK_OFFSET
|
||||
#define OBJC_FORWARDING_STACK_OFFSET 0
|
||||
#endif
|
||||
|
||||
#ifndef OBJC_FORWARDING_MIN_OFFSET
|
||||
#define OBJC_FORWARDING_MIN_OFFSET 0
|
||||
#endif
|
||||
|
||||
#define CUMULATIVE_ARGS int
|
||||
|
||||
#define INIT_CUMULATIVE_ARGS(CUM) ((CUM) = 0)
|
||||
|
||||
#define FUNCTION_ARG_ENCODING(CUM, TYPE, STACK_ARGSIZE) \
|
||||
({ id encoding; \
|
||||
const char* type = [(TYPE) cString]; \
|
||||
int align = objc_alignof_type(type); \
|
||||
int type_size = objc_sizeof_type(type); \
|
||||
\
|
||||
(CUM) = ROUND((CUM), align); \
|
||||
if(type_size < sizeof(int)) \
|
||||
(CUM) += sizeof(int) - ROUND(type_size, align); \
|
||||
encoding = [NSString stringWithFormat:@"%@%d", \
|
||||
(TYPE), \
|
||||
(CUM) + OBJC_FORWARDING_STACK_OFFSET]; \
|
||||
if((*type == _C_STRUCT_B || *type == _C_UNION_B || *type == _C_ARY_B) \
|
||||
&& type_size > 2) \
|
||||
(STACK_ARGSIZE) = (CUM) + ROUND(type_size, align); \
|
||||
else (STACK_ARGSIZE) = (CUM) + ROUND(type_size, align); \
|
||||
(CUM) += type_size < sizeof(int) \
|
||||
? ROUND(type_size, align) \
|
||||
: ROUND(type_size, sizeof(void*)); \
|
||||
encoding; })
|
||||
|
||||
#endif /* m68k */
|
||||
|
||||
#if defined(sparc) && defined(solaris)
|
||||
|
||||
#ifndef OBJC_FORWARDING_STACK_OFFSET
|
||||
#define OBJC_FORWARDING_STACK_OFFSET 0
|
||||
#endif
|
||||
|
||||
#ifndef OBJC_FORWARDING_MIN_OFFSET
|
||||
#define OBJC_FORWARDING_MIN_OFFSET 0
|
||||
#endif
|
||||
|
||||
/* From config/sparc/sparc.h in the GCC sources:
|
||||
|
||||
On SPARC the first six args are normally in registers
|
||||
and the rest are pushed. Any arg that starts within the first 6 words
|
||||
is at least partially passed in a register unless its data type forbids.
|
||||
For v9, the first 6 int args are passed in regs and the first N
|
||||
float args are passed in regs (where N is such that %f0-15 are filled).
|
||||
The rest are pushed. Any arg that starts within the first 6 words
|
||||
is at least partially passed in a register unless its data type forbids.
|
||||
|
||||
...
|
||||
|
||||
The SPARC ABI stipulates passing struct arguments (of any size) and
|
||||
(!v9) quad-precision floats by invisible reference.
|
||||
*/
|
||||
|
||||
enum sparc_arg_location { IN_REGS = 0, ON_STACK = 1 };
|
||||
|
||||
struct sparc_args {
|
||||
int offsets[2]; /* 0 for args in regs, 1 for the rest of args on stack */
|
||||
int onStack;
|
||||
};
|
||||
|
||||
#define CUMULATIVE_ARGS struct sparc_args
|
||||
|
||||
/* Initialize a variable of type CUMULATIVE_ARGS. This macro is called before
|
||||
processing the first argument of a method. */
|
||||
|
||||
#define INIT_CUMULATIVE_ARGS(CUM) \
|
||||
({ (CUM).offsets[0] = 8; /* encoding in regs starts from 8 */ \
|
||||
(CUM).offsets[1] = 20; /* encoding in regs starts from 20 or 24 */ \
|
||||
(CUM).onStack = NO; })
|
||||
|
||||
#define GET_SPARC_ARG_LOCATION(CUM, CSTRING_TYPE, TYPESIZE) \
|
||||
((CUM).onStack \
|
||||
? ON_STACK \
|
||||
: ((CUM).offsets[IN_REGS] + TYPESIZE <= 6 * sizeof(int) + 8 \
|
||||
? (((CUM).offsets[IN_REGS] + TYPESIZE <= 6 * sizeof(int) + 4 \
|
||||
? 0 : ((CUM).offsets[ON_STACK] += 4)),\
|
||||
IN_REGS) \
|
||||
: ((CUM).onStack = YES, ON_STACK)))
|
||||
|
||||
#define FUNCTION_ARG_ENCODING(CUM, TYPE, STACK_ARGSIZE) \
|
||||
({ id encoding; \
|
||||
const char* type = [(TYPE) cString]; \
|
||||
int align = objc_alignof_type(type); \
|
||||
int type_size = objc_sizeof_type(type); \
|
||||
int arg_location = GET_SPARC_ARG_LOCATION(CUM, type, type_size); \
|
||||
\
|
||||
(CUM).offsets[arg_location] \
|
||||
= ROUND((CUM).offsets[arg_location], align); \
|
||||
if(type_size < sizeof(int)) \
|
||||
(CUM).offsets[arg_location] += sizeof(int) - ROUND(type_size, align); \
|
||||
encoding = [NSString stringWithFormat: \
|
||||
(arg_location == IN_REGS ? @"%@+%d" : @"%@%d"), \
|
||||
(TYPE), \
|
||||
(arg_location == IN_REGS \
|
||||
? ((CUM).offsets[arg_location] \
|
||||
+ OBJC_FORWARDING_STACK_OFFSET) \
|
||||
: (CUM).offsets[arg_location])]; \
|
||||
if(arg_location == ON_STACK) { \
|
||||
if((*type == _C_STRUCT_B || *type == _C_UNION_B \
|
||||
|| *type == _C_ARY_B)) \
|
||||
(STACK_ARGSIZE) = (CUM).offsets[ON_STACK] + ROUND(type_size, align); \
|
||||
else (STACK_ARGSIZE) = (CUM).offsets[ON_STACK] + type_size; \
|
||||
} \
|
||||
(CUM).offsets[arg_location] += \
|
||||
type_size < sizeof(int) \
|
||||
? ROUND(type_size, align) \
|
||||
: ROUND(type_size, sizeof(void*)); \
|
||||
encoding; })
|
||||
|
||||
#endif /* sparc solaris */
|
||||
|
||||
#if defined(sparc) && defined(linux)
|
||||
|
||||
#ifndef OBJC_FORWARDING_STACK_OFFSET
|
||||
#define OBJC_FORWARDING_STACK_OFFSET 0
|
||||
#endif
|
||||
|
||||
#ifndef OBJC_FORWARDING_MIN_OFFSET
|
||||
#define OBJC_FORWARDING_MIN_OFFSET 0
|
||||
#endif
|
||||
|
||||
enum sparc_arg_location { IN_REGS = 0, ON_STACK = 1 };
|
||||
|
||||
struct sparc_args {
|
||||
int offsets[2]; /* 0 for args in regs, 1 for the rest of args on stack */
|
||||
int onStack;
|
||||
};
|
||||
|
||||
#define CUMULATIVE_ARGS struct sparc_args
|
||||
|
||||
#define INIT_CUMULATIVE_ARGS(CUM) \
|
||||
({ (CUM).offsets[0] = 8; /* encoding in regs starts from 8 */ \
|
||||
(CUM).offsets[1] = 20; /* encoding in regs starts from 20 or 24 */ \
|
||||
(CUM).onStack = NO; })
|
||||
|
||||
#define GET_SPARC_ARG_LOCATION(CUM, CSTRING_TYPE, TYPESIZE) \
|
||||
((CUM).onStack \
|
||||
? ON_STACK \
|
||||
: ((CUM).offsets[IN_REGS] + TYPESIZE <= 6 * sizeof(int) + 8 \
|
||||
? (((CUM).offsets[IN_REGS] + TYPESIZE <= 6 * sizeof(int) + 4 \
|
||||
? 0 : ((CUM).offsets[ON_STACK] += 4)),\
|
||||
IN_REGS) \
|
||||
: ((CUM).onStack = YES, ON_STACK)))
|
||||
|
||||
#define FUNCTION_ARG_ENCODING(CUM, TYPE, STACK_ARGSIZE) \
|
||||
({ id encoding; \
|
||||
const char* type = [(TYPE) cString]; \
|
||||
int align = objc_alignof_type(type); \
|
||||
int type_size = objc_sizeof_type(type); \
|
||||
int arg_location = GET_SPARC_ARG_LOCATION(CUM, type, type_size); \
|
||||
\
|
||||
(CUM).offsets[arg_location] \
|
||||
= ROUND((CUM).offsets[arg_location], align); \
|
||||
if(type_size < sizeof(int)) \
|
||||
(CUM).offsets[arg_location] += sizeof(int) - ROUND(type_size, align); \
|
||||
encoding = [NSString stringWithFormat: \
|
||||
(arg_location == IN_REGS ? @"%@+%d" : @"%@%d"), \
|
||||
(TYPE), \
|
||||
(arg_location == IN_REGS \
|
||||
? ((CUM).offsets[arg_location] \
|
||||
+ OBJC_FORWARDING_STACK_OFFSET) \
|
||||
: (CUM).offsets[arg_location])]; \
|
||||
if(arg_location == ON_STACK) { \
|
||||
if((*type == _C_STRUCT_B || *type == _C_UNION_B \
|
||||
|| *type == _C_ARY_B)) \
|
||||
(STACK_ARGSIZE) = (CUM).offsets[ON_STACK] + ROUND(type_size, align); \
|
||||
else (STACK_ARGSIZE) = (CUM).offsets[ON_STACK] + type_size; \
|
||||
} \
|
||||
(CUM).offsets[arg_location] += \
|
||||
type_size < sizeof(int) \
|
||||
? ROUND(type_size, align) \
|
||||
: ROUND(type_size, sizeof(void*)); \
|
||||
encoding; })
|
||||
|
||||
#endif /* sparc linux */
|
||||
|
||||
|
||||
|
||||
#ifndef FUNCTION_ARG_ENCODING
|
||||
|
||||
#ifndef OBJC_FORWARDING_STACK_OFFSET
|
||||
#define OBJC_FORWARDING_STACK_OFFSET 0
|
||||
#endif
|
||||
|
||||
#ifndef OBJC_FORWARDING_MIN_OFFSET
|
||||
#define OBJC_FORWARDING_MIN_OFFSET 0
|
||||
#endif
|
||||
|
||||
#define CUMULATIVE_ARGS int
|
||||
|
||||
#define INIT_CUMULATIVE_ARGS(CUM) ((CUM) = 0)
|
||||
|
||||
#define FUNCTION_ARG_ENCODING(CUM, TYPE, STACK_ARGSIZE) \
|
||||
({ id encoding; \
|
||||
const char* type = [(TYPE) cString]; \
|
||||
int align = objc_alignof_type(type); \
|
||||
int type_size = objc_sizeof_type(type); \
|
||||
\
|
||||
(CUM) = ROUND((CUM), align); \
|
||||
encoding = [NSString stringWithFormat:@"%@%d", \
|
||||
(TYPE), \
|
||||
(CUM) + OBJC_FORWARDING_STACK_OFFSET]; \
|
||||
(STACK_ARGSIZE) = (CUM) + type_size; \
|
||||
(CUM) += ROUND(type_size, sizeof(void*)); \
|
||||
encoding; })
|
||||
|
||||
#endif /* generic */
|
||||
|
||||
/*
|
||||
* End of libFoundation macros.
|
||||
*/
|
||||
|
||||
|
||||
static NSString*
|
||||
isolate_type(const char* types)
|
||||
{
|
||||
const char* p = objc_skip_typespec(types);
|
||||
return [NSString stringWithCString:types length:(unsigned)(p - types)];
|
||||
}
|
||||
|
||||
static int
|
||||
types_get_size_of_arguments(const char *types)
|
||||
{
|
||||
|
@ -77,29 +442,55 @@ rtn_type_is_oneway(const char * types)
|
|||
|
||||
+ (NSMethodSignature*) signatureWithObjCTypes: (const char*)t
|
||||
{
|
||||
NSMethodSignature *newMs = [[NSMethodSignature alloc] autorelease];
|
||||
const char *positionOfSizeInfo;
|
||||
const char *positionOfFirstParam;
|
||||
int len;
|
||||
NSMethodSignature *newMs = [NSMethodSignature alloc];
|
||||
#if 0
|
||||
len = strlen(t);
|
||||
#else
|
||||
len = strlen(t) + 1; // For the last '\0'
|
||||
#endif
|
||||
OBJC_MALLOC(newMs->types, char, len);
|
||||
memcpy(newMs->types, t, len);
|
||||
#if 0
|
||||
len = strlen(t); /* xxx */
|
||||
#else
|
||||
{
|
||||
char * endof_ret_encoding = strrchr(t, '0');
|
||||
len = endof_ret_encoding - t + 1; // +2?
|
||||
}
|
||||
#endif
|
||||
OBJC_MALLOC(newMs->returnTypes, char, len);
|
||||
memcpy(newMs->returnTypes, t, len);
|
||||
newMs->returnTypes[len-1] = '\0'; // ???
|
||||
newMs->argFrameLength = types_get_size_of_arguments(t);
|
||||
newMs->returnFrameLength = objc_sizeof_type(t);
|
||||
newMs->numArgs = types_get_number_of_arguments(t);
|
||||
|
||||
positionOfSizeInfo = objc_skip_typespec(t);
|
||||
|
||||
if (!isdigit(*positionOfSizeInfo))
|
||||
{
|
||||
CUMULATIVE_ARGS cumulative_args;
|
||||
int stack_argsize = 0;
|
||||
id encoding = [[NSMutableString new] autorelease];
|
||||
const char* retval = t;
|
||||
|
||||
/* Skip returned value. */
|
||||
t = objc_skip_typespec(t);
|
||||
|
||||
newMs->numArgs = 0;
|
||||
|
||||
INIT_CUMULATIVE_ARGS(cumulative_args);
|
||||
while(*t) {
|
||||
[encoding appendString:
|
||||
FUNCTION_ARG_ENCODING(cumulative_args,
|
||||
isolate_type(t),
|
||||
stack_argsize)];
|
||||
t = objc_skip_typespec(t);
|
||||
newMs->numArgs++;
|
||||
}
|
||||
encoding = [NSString stringWithFormat:@"%@%d%@",
|
||||
isolate_type(retval), stack_argsize, encoding];
|
||||
newMs->types = objc_malloc([encoding cStringLength]+1);
|
||||
[encoding getCString: newMs->types];
|
||||
}
|
||||
else
|
||||
{
|
||||
newMs->types = objc_malloc(strlen(t) + 1);
|
||||
strcpy(newMs->types, t);
|
||||
newMs->numArgs = types_get_number_of_arguments(newMs->types);
|
||||
}
|
||||
positionOfFirstParam = objc_skip_typespec(newMs->types);
|
||||
len = positionOfFirstParam - newMs->types;
|
||||
newMs->returnTypes = objc_malloc(len + 1);
|
||||
memcpy(newMs->returnTypes, newMs->types, len);
|
||||
newMs->returnTypes[len] = '\0';
|
||||
newMs->argFrameLength = types_get_size_of_arguments(newMs->types);
|
||||
if (*newMs->types == _C_VOID)
|
||||
newMs->returnFrameLength = 0;
|
||||
else
|
||||
newMs->returnFrameLength = objc_sizeof_type(newMs->types);
|
||||
return newMs;
|
||||
}
|
||||
|
||||
|
@ -170,7 +561,7 @@ rtn_type_is_oneway(const char * types)
|
|||
size = offset - preoffset;
|
||||
}
|
||||
#endif // m68k
|
||||
return (NSArgumentInfo){offset, size, result_type};
|
||||
return (NSArgumentInfo){offset, size, (char*)result_type};
|
||||
}
|
||||
|
||||
- (unsigned) frameLength
|
||||
|
@ -200,8 +591,8 @@ rtn_type_is_oneway(const char * types)
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
OBJC_FREE(types);
|
||||
OBJC_FREE(returnTypes);
|
||||
objc_free(types);
|
||||
objc_free(returnTypes);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
|
147
Source/mframe.m
147
Source/mframe.m
|
@ -192,8 +192,9 @@ method_types_get_next_argument (arglist_t argf,
|
|||
e.g. an argument declared (out char*). */
|
||||
|
||||
BOOL
|
||||
mframe_dissect_call (arglist_t argframe, const char *type,
|
||||
void (*encoder)(int,void*,const char*,int))
|
||||
mframe_dissect_call_opts (arglist_t argframe, const char *type,
|
||||
void (*encoder)(int,void*,const char*,int),
|
||||
BOOL pass_pointers)
|
||||
{
|
||||
unsigned flags;
|
||||
char *datum;
|
||||
|
@ -256,11 +257,6 @@ mframe_dissect_call (arglist_t argframe, const char *type,
|
|||
break;
|
||||
|
||||
case _C_PTR:
|
||||
/* 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 OUT parameter,
|
||||
or if it not explicitly qualified as an IN parameter,
|
||||
then we will have to get the value pointed to again after
|
||||
|
@ -268,11 +264,22 @@ mframe_dissect_call (arglist_t argframe, const char *type,
|
|||
it. Set OUT_PARAMETERS accordingly. */
|
||||
if ((flags & _F_OUT) || !(flags & _F_IN))
|
||||
out_parameters = YES;
|
||||
/* 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))
|
||||
(*encoder) (argnum, *(void**)datum, type, flags);
|
||||
if (pass_pointers) {
|
||||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
(*encoder) (argnum, datum, type, flags);
|
||||
}
|
||||
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))
|
||||
(*encoder) (argnum, *(void**)datum, type, flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case _C_STRUCT_B:
|
||||
|
@ -303,6 +310,13 @@ mframe_dissect_call (arglist_t argframe, const char *type,
|
|||
return out_parameters;
|
||||
}
|
||||
|
||||
BOOL
|
||||
mframe_dissect_call (arglist_t argframe, const char *type,
|
||||
void (*encoder)(int,void*,const char*,int))
|
||||
{
|
||||
return mframe_dissect_call_opts(argframe, type, encoder, NO);
|
||||
}
|
||||
|
||||
|
||||
/* mframe_do_call()
|
||||
|
||||
|
@ -370,12 +384,17 @@ mframe_dissect_call (arglist_t argframe, const char *type,
|
|||
pass-by-reference parameters. The ENCODER function should place
|
||||
the value at memory location DATA wherever the user wants to
|
||||
record the ARGNUM'th return value.
|
||||
|
||||
PASS_POINTERS is a flag saying whether pointers should be passed
|
||||
as pointers (for local stuff) or should be assumed to point to a
|
||||
single data item (for distributed objects).
|
||||
*/
|
||||
|
||||
void
|
||||
mframe_do_call (const char *encoded_types,
|
||||
mframe_do_call_opts (const char *encoded_types,
|
||||
void(*decoder)(int,void*,const char*),
|
||||
void(*encoder)(int,void*,const char*,int))
|
||||
void(*encoder)(int,void*,const char*,int),
|
||||
BOOL pass_pointers)
|
||||
{
|
||||
/* The method type string obtained from the target's OBJC_METHOD
|
||||
structure for the selector we're sending. */
|
||||
|
@ -584,11 +603,6 @@ mframe_do_call (const char *encoded_types,
|
|||
break;
|
||||
|
||||
case _C_PTR:
|
||||
/* 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. */
|
||||
tmptype++;
|
||||
/* 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
|
||||
|
@ -596,16 +610,27 @@ mframe_do_call (const char *encoded_types,
|
|||
it. Set OUT_PARAMETERS accordingly. */
|
||||
if ((flags & _F_OUT) || !(flags & _F_IN))
|
||||
out_parameters = YES;
|
||||
/* Allocate some memory to be pointed to, and to hold the
|
||||
value. Note that it is allocated on the stack, and
|
||||
methods that want to keep the data pointed to, will have
|
||||
to make their own copies. */
|
||||
*(void**)datum = alloca (objc_sizeof_type (tmptype));
|
||||
/* If the pointer's value is qualified as an IN parameter,
|
||||
or not explicity qualified as an OUT parameter, then
|
||||
decode it. */
|
||||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
(*decoder) (argnum, *(void**)datum, tmptype);
|
||||
if (pass_pointers) {
|
||||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
(*decoder) (argnum, datum, tmptype);
|
||||
}
|
||||
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. */
|
||||
tmptype++;
|
||||
/* Allocate some memory to be pointed to, and to hold the
|
||||
value. Note that it is allocated on the stack, and
|
||||
methods that want to keep the data pointed to, will have
|
||||
to make their own copies. */
|
||||
*(void**)datum = alloca (objc_sizeof_type (tmptype));
|
||||
/* If the pointer's value is qualified as an IN parameter,
|
||||
or not explicity qualified as an OUT parameter, then
|
||||
decode it. */
|
||||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
(*decoder) (argnum, *(void**)datum, tmptype);
|
||||
}
|
||||
break;
|
||||
|
||||
case _C_STRUCT_B:
|
||||
|
@ -684,11 +709,16 @@ mframe_do_call (const char *encoded_types,
|
|||
break;
|
||||
|
||||
case _C_PTR:
|
||||
/* The argument is a pointer to something; increment TYPE
|
||||
so we can see what it is a pointer to. */
|
||||
tmptype++;
|
||||
/* Encode the value that was pointed to. */
|
||||
(*encoder) (-1, *(void**)retframe, tmptype, flags);
|
||||
if (pass_pointers) {
|
||||
(*encoder) (-1, retframe, tmptype, flags);
|
||||
}
|
||||
else {
|
||||
/* The argument is a pointer to something; increment TYPE
|
||||
so we can see what it is a pointer to. */
|
||||
tmptype++;
|
||||
/* Encode the value that was pointed to. */
|
||||
(*encoder) (-1, *(void**)retframe, tmptype, flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case _C_STRUCT_B:
|
||||
|
@ -816,6 +846,14 @@ mframe_do_call (const char *encoded_types,
|
|||
return;
|
||||
}
|
||||
|
||||
void
|
||||
mframe_do_call (const char *encoded_types,
|
||||
void(*decoder)(int,void*,const char*),
|
||||
void(*encoder)(int,void*,const char*,int))
|
||||
{
|
||||
mframe_do_call_opts(encoded_types, decoder, encoder, NO);
|
||||
}
|
||||
|
||||
|
||||
/* mframe_build_return()
|
||||
|
||||
|
@ -835,10 +873,11 @@ mframe_do_call (const char *encoded_types,
|
|||
*/
|
||||
|
||||
retval_t
|
||||
mframe_build_return (arglist_t argframe,
|
||||
mframe_build_return_opts (arglist_t argframe,
|
||||
const char *type,
|
||||
BOOL out_parameters,
|
||||
void(*decoder)(int,void*,const char*,int))
|
||||
void(*decoder)(int,void*,const char*,int),
|
||||
BOOL pass_pointers)
|
||||
{
|
||||
/* A pointer to the memory that will hold the return value. */
|
||||
retval_t retframe = NULL;
|
||||
|
@ -955,17 +994,22 @@ mframe_build_return (arglist_t argframe,
|
|||
switch (*tmptype)
|
||||
{
|
||||
case _C_PTR:
|
||||
/* We are returning a pointer to something. */
|
||||
/* Increment TYPE so we can see what it is a pointer to. */
|
||||
tmptype++;
|
||||
/* Allocate some memory to hold the value we're pointing to. */
|
||||
*(void**)retframe =
|
||||
objc_malloc (objc_sizeof_type (tmptype));
|
||||
/* We are responsible for making sure this memory gets free'd
|
||||
eventually. Ask MallocAddress class to autorelease it. */
|
||||
[MallocAddress autoreleaseMallocAddress: *(void**)retframe];
|
||||
/* Decode the return value into the memory we allocated. */
|
||||
(*decoder) (-1, *(void**)retframe, tmptype, flags);
|
||||
if (pass_pointers) {
|
||||
(*decoder) (-1, retframe, tmptype, flags);
|
||||
}
|
||||
else {
|
||||
/* We are returning a pointer to something. */
|
||||
/* Increment TYPE so we can see what it is a pointer to. */
|
||||
tmptype++;
|
||||
/* Allocate some memory to hold the value we're pointing to. */
|
||||
*(void**)retframe =
|
||||
objc_malloc (objc_sizeof_type (tmptype));
|
||||
/* We are responsible for making sure this memory gets free'd
|
||||
eventually. Ask MallocAddress class to autorelease it. */
|
||||
[MallocAddress autoreleaseMallocAddress: *(void**)retframe];
|
||||
/* Decode the return value into the memory we allocated. */
|
||||
(*decoder) (-1, *(void**)retframe, tmptype, flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case _C_STRUCT_B:
|
||||
|
@ -1120,3 +1164,12 @@ mframe_build_return (arglist_t argframe,
|
|||
return retframe;
|
||||
}
|
||||
|
||||
retval_t
|
||||
mframe_build_return (arglist_t argframe,
|
||||
const char *type,
|
||||
BOOL out_parameters,
|
||||
void(*decoder)(int,void*,const char*,int))
|
||||
{
|
||||
return mframe_build_return_opts(argframe,type,out_parameters,decoder,NO);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue