Improvements to object-ownership management in

"-scm" mode.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@5330 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Matthias Köppe 2003-11-18 15:52:49 +00:00
commit dda57d7224
5 changed files with 133 additions and 63 deletions

View file

@ -19,7 +19,7 @@
#define gh_scm2double(a) scm_num2dbl(a, FUNC_NAME) #define gh_scm2double(a) scm_num2dbl(a, FUNC_NAME)
#define gh_scm2int(a) scm_num2int(a, SCM_ARG1, FUNC_NAME) #define gh_scm2int(a) scm_num2int(a, SCM_ARG1, FUNC_NAME)
#define gh_scm2long(a) scm_num2long(a, SCM_ARG1, FUNC_NAME) #define gh_scm2long(a) scm_num2long(a, SCM_ARG1, FUNC_NAME)
#define gh_scm2newstr SWIG_scm2newstr #define gh_scm2newstr SWIG_Guile_scm2newstr
#define gh_scm2ulong(a) scm_num2ulong(a, SCM_ARG1, FUNC_NAME) #define gh_scm2ulong(a) scm_num2ulong(a, SCM_ARG1, FUNC_NAME)
#define gh_ulong2scm scm_ulong2num #define gh_ulong2scm scm_ulong2num
#define gh_long2scm scm_long2num #define gh_long2scm scm_long2num

View file

@ -25,6 +25,10 @@ extern "C" {
SWIG_Guile_MustGetPtr(s, type, argnum, FUNC_NAME) SWIG_Guile_MustGetPtr(s, type, argnum, FUNC_NAME)
#define SWIG_NewPointerObj(ptr, type, owner) \ #define SWIG_NewPointerObj(ptr, type, owner) \
SWIG_Guile_MakePtr((void*)ptr, type) SWIG_Guile_MakePtr((void*)ptr, type)
/* Ignore object-ownership changes in gh mode */
#define SWIG_Guile_MarkPointerNoncollectable(s) (s)
#define SWIG_Guile_MarkPointerDestroyed(s) (s)
#if defined(SWIG_NOINCLUDE) #if defined(SWIG_NOINCLUDE)
# define SWIGSTATIC # define SWIGSTATIC

View file

@ -22,8 +22,8 @@ typedef struct swig_guile_clientdata {
SCM goops_class; SCM goops_class;
} swig_guile_clientdata; } swig_guile_clientdata;
#define SWIG_scm2str(s) SWIG_scm2newstr(s, NULL) #define SWIG_scm2str(s) \
SWIG_Guile_scm2newstr(s, NULL)
#define SWIG_malloc(size) \ #define SWIG_malloc(size) \
SCM_MUST_MALLOC(size) SCM_MUST_MALLOC(size)
#define SWIG_free(mem) \ #define SWIG_free(mem) \
@ -40,7 +40,7 @@ typedef struct swig_guile_clientdata {
#ifdef SWIG_NOINCLUDE #ifdef SWIG_NOINCLUDE
/* Interface helper function */ /* Interface helper function */
SWIGIMPORT(char *) SWIG_scm2newstr(SCM str, size_t *len); SWIGIMPORT(char *) SWIG_Guile_scm2newstr(SCM str, size_t *len);
/* Register SWIG smobs with Guile. */ /* Register SWIG smobs with Guile. */
SWIGIMPORT(void) SWIG_Guile_Init(); SWIGIMPORT(void) SWIG_Guile_Init();
@ -57,12 +57,18 @@ SWIGIMPORT(int) SWIG_Guile_GetArgs(SCM *dest, SCM rest, int reqargs, int optargs
/* Propagate client data to equivalent types */ /* Propagate client data to equivalent types */
SWIGIMPORT(void) SWIGIMPORT(void)
SWIG_Guile_PropagateClientData(swig_type_info *type); SWIG_Guile_PropagateClientData(swig_type_info *type);
/* Make a pointer object non-collectable */
SWIGIMPORT(void)
SWIG_Guile_MarkPointerNoncollectable(SCM s);
/* Mark a pointer object destroyed */
SWIGIMPORT(void)
SWIG_Guile_MarkPointerDestroyed(SCM s);
#else #else
SWIGRUNTIME(char *) SWIGRUNTIME(char *)
SWIG_scm2newstr(SCM str, size_t *len) { SWIG_Guile_scm2newstr(SCM str, size_t *len) {
#define FUNC_NAME "swig_scm2newstr" #define FUNC_NAME "SWIG_Guile_scm2newstr"
char *ret; char *ret;
size_t l; size_t l;
@ -78,7 +84,8 @@ SWIG_scm2newstr(SCM str, size_t *len) {
} }
static scm_t_bits swig_tag = 0; static scm_t_bits swig_tag = 0;
static scm_t_bits swig_collected_tag = 0; static scm_t_bits swig_collectable_tag = 0;
static scm_t_bits swig_destroyed_tag = 0;
static SCM swig_make_func = SCM_EOL; static SCM swig_make_func = SCM_EOL;
static SCM swig_keyword = SCM_EOL; static SCM swig_keyword = SCM_EOL;
static SCM swig_symbol = SCM_EOL; static SCM swig_symbol = SCM_EOL;
@ -93,7 +100,7 @@ SWIG_Guile_NewPointerObj(void *ptr, swig_type_info *type, int owner)
SCM smob; SCM smob;
swig_guile_clientdata *cdata = (swig_guile_clientdata *) type->clientdata; swig_guile_clientdata *cdata = (swig_guile_clientdata *) type->clientdata;
if (owner) if (owner)
SCM_NEWSMOB2(smob, swig_collected_tag, ptr, (void *) type); SCM_NEWSMOB2(smob, swig_collectable_tag, ptr, (void *) type);
else else
SCM_NEWSMOB2(smob, swig_tag, ptr, (void *) type); SCM_NEWSMOB2(smob, swig_tag, ptr, (void *) type);
@ -124,7 +131,8 @@ SWIG_Guile_ConvertPtr(SCM s, void **result, swig_type_info *type, int flags)
if (SCM_NULLP(smob)) { if (SCM_NULLP(smob)) {
*result = NULL; *result = NULL;
return 0; return 0;
} else if (SCM_SMOB_PREDICATE(swig_tag, smob) || SCM_SMOB_PREDICATE(swig_collected_tag, smob)) { } else if (SCM_SMOB_PREDICATE(swig_tag, smob) || SCM_SMOB_PREDICATE(swig_collectable_tag, smob)) {
/* we do not accept smobs representing destroyed pointers */
from = (swig_type_info *) SCM_CELL_WORD_2(smob); from = (swig_type_info *) SCM_CELL_WORD_2(smob);
if (!from) return 1; if (!from) return 1;
if (type) { if (type) {
@ -155,16 +163,44 @@ SWIG_Guile_MustGetPtr (SCM s, swig_type_info *type,
return result; return result;
} }
/* Mark a pointer object non-collectable */
SWIGRUNTIME(void)
SWIG_Guile_MarkPointerNoncollectable(SCM s)
{
SCM smob = SWIG_Guile_GetSmob(s);
if (!SCM_NULLP(smob)) {
if (SCM_SMOB_PREDICATE(swig_tag, smob) || SCM_SMOB_PREDICATE(swig_collectable_tag, smob)) {
SCM_SET_CELL_TYPE(smob, swig_tag);
}
else scm_wrong_type_arg(NULL, 0, s);
}
}
/* Mark a pointer object destroyed */
SWIGIMPORT(void)
SWIG_Guile_MarkPointerDestroyed(SCM s)
{
SCM smob = SWIG_Guile_GetSmob(s);
if (!SCM_NULLP(smob)) {
if (SCM_SMOB_PREDICATE(swig_tag, smob) || SCM_SMOB_PREDICATE(swig_collectable_tag, smob)) {
SCM_SET_CELL_TYPE(smob, swig_destroyed_tag);
}
else scm_wrong_type_arg(NULL, 0, s);
}
}
/* Init */ /* Init */
static int static int
print_swig (SCM swig_smob, SCM port, scm_print_state *pstate) print_swig_aux (SCM swig_smob, SCM port, scm_print_state *pstate, const char *attribute)
{ {
swig_type_info *type; swig_type_info *type;
type = (swig_type_info *) SCM_CELL_WORD_2(swig_smob); type = (swig_type_info *) SCM_CELL_WORD_2(swig_smob);
if (type) { if (type) {
scm_puts((char *) "#<swig ", port); scm_puts((char *) "#<", port);
scm_puts(attribute, port);
scm_puts("swig ", port);
if (type->str != NULL) if (type->str != NULL)
scm_puts(type->str, port); scm_puts(type->str, port);
else else
@ -179,32 +215,29 @@ print_swig (SCM swig_smob, SCM port, scm_print_state *pstate)
} }
} }
static int static int
print_collected_swig (SCM swig_smob, SCM port, scm_print_state *pstate) print_swig (SCM swig_smob, SCM port, scm_print_state *pstate)
{ {
swig_type_info *type; return print_swig_aux(swig_smob, port, pstate, "");
}
type = (swig_type_info *) SCM_CELL_WORD_2(swig_smob); static int
if (type) { print_collectable_swig (SCM swig_smob, SCM port, scm_print_state *pstate)
scm_puts((char *) "#<collected swig ", port); {
if (type->str != NULL) return print_swig_aux(swig_smob, port, pstate, "collectable ");
scm_puts(type->str, port); }
else
scm_puts(type->name, port); static int
scm_puts((char *) " ", port); print_destroyed_swig (SCM swig_smob, SCM port, scm_print_state *pstate)
scm_intprint((long) SCM_CELL_WORD_1(swig_smob), 16, port); {
scm_puts((char *) ">", port); return print_swig_aux(swig_smob, port, pstate, "destroyed ");
/* non-zero means success */
return 1;
} else {
return 0;
}
} }
static SCM static SCM
equalp_swig (SCM A, SCM B) equalp_swig (SCM A, SCM B)
{ {
if (SCM_CAR(A) == SCM_CAR(B) && SCM_CELL_WORD_1(A) == SCM_CELL_WORD_1(B) if (SCM_CELL_WORD_0(A) == SCM_CELL_WORD_0(B) && SCM_CELL_WORD_1(A) == SCM_CELL_WORD_1(B)
&& SCM_CELL_WORD_2(A) == SCM_CELL_WORD_2(B)) && SCM_CELL_WORD_2(A) == SCM_CELL_WORD_2(B))
return SCM_BOOL_T; return SCM_BOOL_T;
else return SCM_BOOL_F; else return SCM_BOOL_F;
@ -230,16 +263,22 @@ SWIG_Guile_Init ()
scm_set_smob_equalp(swig_tag, equalp_swig); scm_set_smob_equalp(swig_tag, equalp_swig);
} }
if (!swig_collected_tag) { if (!swig_collectable_tag) {
swig_collected_tag = scm_make_smob_type((char*)"collected swig", 0); swig_collectable_tag = scm_make_smob_type((char*)"collectable swig", 0);
scm_set_smob_print(swig_collected_tag, print_collected_swig); scm_set_smob_print(swig_collectable_tag, print_collectable_swig);
scm_set_smob_equalp(swig_collected_tag, equalp_swig); scm_set_smob_equalp(swig_collectable_tag, equalp_swig);
scm_set_smob_free(swig_collected_tag, free_swig); scm_set_smob_free(swig_collectable_tag, free_swig);
}
if (!swig_destroyed_tag) {
swig_destroyed_tag = scm_make_smob_type((char*)"destroyed swig", 0);
scm_set_smob_print(swig_destroyed_tag, print_destroyed_swig);
scm_set_smob_equalp(swig_destroyed_tag, equalp_swig);
} }
swig_make_func = scm_permanent_object( swig_make_func = scm_permanent_object(
scm_variable_ref(scm_c_module_lookup(scm_c_resolve_module("oop goops"), "make"))); scm_variable_ref(scm_c_module_lookup(scm_c_resolve_module("oop goops"), "make")));
swig_keyword = scm_permanent_object(scm_c_make_keyword("init-smob")); swig_keyword = scm_permanent_object(scm_c_make_keyword((char*) "init-smob"));
swig_symbol = scm_permanent_object(scm_str2symbol("swig-smob")); swig_symbol = scm_permanent_object(scm_str2symbol("swig-smob"));
} }

View file

@ -1,6 +1,6 @@
/* pointer-in-out.i --- Guile typemaps for passing -*- c -*- pointers indirectly /* pointer-in-out.i --- Guile typemaps for passing -*- c -*- pointers indirectly
Copyright (C) 2001 Matthias Koeppe <mkoeppe@mail.math.uni-magdeburg.de> Copyright (C) 2001, 2003 Matthias Koeppe <mkoeppe@mail.math.uni-magdeburg.de>
$Header$ $Header$
*/ */
@ -17,6 +17,15 @@
The address of a variable containing this pointer will be The address of a variable containing this pointer will be
passed to the function. passed to the function.
func(int **INPUT_CONSUMED)
Likewise, but mark the pointer object as not garbage
collectable.
func(int **INPUT_DESTROYED)
Likewise, but mark the pointer object as destroyed.
func(int **OUTPUT) func(int **OUTPUT)
Scheme wrapper will take no arguments. The address of an int * Scheme wrapper will take no arguments. The address of an int *
@ -25,6 +34,10 @@
becomes an extra return value. (See the documentation on how becomes an extra return value. (See the documentation on how
to deal with multiple values.) to deal with multiple values.)
func(int **OUTPUT_NONCOLLECTABLE)
Likewise, but make the pointer object not garbage collectable.
func(int **BOTH) func(int **BOTH)
func(int **INOUT) func(int **INOUT)
@ -42,12 +55,34 @@
$1 = &temp; $1 = &temp;
} }
%typemap(in, numinputs=0) PTRTYPE *OUTPUT(PTRTYPE temp) %typemap(in, doc="$NAME is of type <" #SCM_TYPE "> and is consumed by the function") PTRTYPE *INPUT_CONSUMED(PTRTYPE temp)
{
if (SWIG_ConvertPtr($input, (void **) &temp, $*descriptor, 0)) {
scm_wrong_type_arg(FUNC_NAME, $argnum, $input);
}
SWIG_Guile_MarkPointerNoncollectable($input);
$1 = &temp;
}
%typemap(in, doc="$NAME is of type <" #SCM_TYPE "> and is consumed by the function") PTRTYPE *INPUT_DESTROYED(PTRTYPE temp)
{
if (SWIG_ConvertPtr($input, (void **) &temp, $*descriptor, 0)) {
scm_wrong_type_arg(FUNC_NAME, $argnum, $input);
}
SWIG_Guile_MarkPointerDestroyed($input);
$1 = &temp;
}
%typemap(in, numinputs=0) PTRTYPE *OUTPUT(PTRTYPE temp),
PTRTYPE *OUTPUT_NONCOLLECTABLE(PTRTYPE temp)
"$1 = &temp;"; "$1 = &temp;";
%typemap(argout, doc="<" #SCM_TYPE ">") PTRTYPE *OUTPUT %typemap(argout, doc="<" #SCM_TYPE ">") PTRTYPE *OUTPUT
"SWIG_APPEND_VALUE(SWIG_NewPointerObj(*$1, $*descriptor, 1));"; "SWIG_APPEND_VALUE(SWIG_NewPointerObj(*$1, $*descriptor, 1));";
%typemap(argout, doc="<" #SCM_TYPE ">") PTRTYPE *OUTPUT_NONCOLLECTABLE
"SWIG_APPEND_VALUE(SWIG_NewPointerObj(*$1, $*descriptor, 0));";
%typemap(in) PTRTYPE *BOTH = PTRTYPE *INPUT; %typemap(in) PTRTYPE *BOTH = PTRTYPE *INPUT;
%typemap(argout) PTRTYPE *BOTH = PTRTYPE *OUTPUT; %typemap(argout) PTRTYPE *BOTH = PTRTYPE *OUTPUT;
%typemap(in) PTRTYPE *INOUT = PTRTYPE *INPUT; %typemap(in) PTRTYPE *INOUT = PTRTYPE *INPUT;

View file

@ -3,31 +3,6 @@
$Header$ */ $Header$ */
/* (11/24/2001) Note to Matthias:
I've replaced all of the documentation related typemaps (indoc, varindoc, outdoc, argoutdoc, ...)
with a typemap parameter of "doc". For example:
%typemap(in, doc="<integer>") int {
...
}
This is somewhat more sane to handle when multi-argument typemaps are used. For example:
%typemap(in, doc="<buffer>") (char *data, int len) {
...
}
See guile.cxx for details of how the typemap parameters actually get accessed.
Also, it's no longer necessary to specify typemaps for 'const' qualifiers. They
now get matched against non-const versions.
Feel free to delete this comment after you've read it.
--- Dave
*/
/* Pointers */ /* Pointers */
%typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { %typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] {
@ -80,6 +55,23 @@
$result = SWIG_NewPointerObj((void *) &$1, $1_descriptor, 0); $result = SWIG_NewPointerObj((void *) &$1, $1_descriptor, 0);
} }
/* Change of object ownership, and interaction of destructor-like functions and the
garbage-collector */
%typemap(in, doc="$NAME is of type <$type> and gets destroyed by the function") SWIGTYPE *DESTROYED {
$1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, 0);
}
%typemap(freearg) SWIGTYPE *DESTROYED {
SWIG_Guile_MarkPointerDestroyed($input);
}
%typemap(in, doc="$NAME is of type <$type> and is consumed by the function") SWIGTYPE *CONSUMED {
$1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, 0);
SWIG_Guile_MarkPointerNoncollectable($input);
}
/* Pass-by-value */ /* Pass-by-value */
%typemap(in) SWIGTYPE($&1_ltype argp) { %typemap(in) SWIGTYPE($&1_ltype argp) {