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:
Adam Fedor 1998-04-30 20:11:42 +00:00
parent 80e0823d87
commit c51efbe1e1
5 changed files with 550 additions and 72 deletions

View file

@ -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.

View file

@ -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

View file

@ -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 */

View file

@ -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];
}

View file

@ -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);
}