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:
parent
7b581cb88a
commit
dda57d7224
5 changed files with 133 additions and 63 deletions
|
|
@ -19,7 +19,7 @@
|
|||
#define gh_scm2double(a) scm_num2dbl(a, 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_scm2newstr SWIG_scm2newstr
|
||||
#define gh_scm2newstr SWIG_Guile_scm2newstr
|
||||
#define gh_scm2ulong(a) scm_num2ulong(a, SCM_ARG1, FUNC_NAME)
|
||||
#define gh_ulong2scm scm_ulong2num
|
||||
#define gh_long2scm scm_long2num
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ extern "C" {
|
|||
SWIG_Guile_MustGetPtr(s, type, argnum, FUNC_NAME)
|
||||
#define SWIG_NewPointerObj(ptr, type, owner) \
|
||||
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)
|
||||
# define SWIGSTATIC
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ typedef struct swig_guile_clientdata {
|
|||
SCM goops_class;
|
||||
} swig_guile_clientdata;
|
||||
|
||||
#define SWIG_scm2str(s) SWIG_scm2newstr(s, NULL)
|
||||
|
||||
#define SWIG_scm2str(s) \
|
||||
SWIG_Guile_scm2newstr(s, NULL)
|
||||
#define SWIG_malloc(size) \
|
||||
SCM_MUST_MALLOC(size)
|
||||
#define SWIG_free(mem) \
|
||||
|
|
@ -40,7 +40,7 @@ typedef struct swig_guile_clientdata {
|
|||
#ifdef SWIG_NOINCLUDE
|
||||
|
||||
/* 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. */
|
||||
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 */
|
||||
SWIGIMPORT(void)
|
||||
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
|
||||
|
||||
SWIGRUNTIME(char *)
|
||||
SWIG_scm2newstr(SCM str, size_t *len) {
|
||||
#define FUNC_NAME "swig_scm2newstr"
|
||||
SWIG_Guile_scm2newstr(SCM str, size_t *len) {
|
||||
#define FUNC_NAME "SWIG_Guile_scm2newstr"
|
||||
char *ret;
|
||||
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_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_keyword = 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;
|
||||
swig_guile_clientdata *cdata = (swig_guile_clientdata *) type->clientdata;
|
||||
if (owner)
|
||||
SCM_NEWSMOB2(smob, swig_collected_tag, ptr, (void *) type);
|
||||
SCM_NEWSMOB2(smob, swig_collectable_tag, ptr, (void *) type);
|
||||
else
|
||||
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)) {
|
||||
*result = NULL;
|
||||
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);
|
||||
if (!from) return 1;
|
||||
if (type) {
|
||||
|
|
@ -155,16 +163,44 @@ SWIG_Guile_MustGetPtr (SCM s, swig_type_info *type,
|
|||
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 */
|
||||
|
||||
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;
|
||||
|
||||
type = (swig_type_info *) SCM_CELL_WORD_2(swig_smob);
|
||||
if (type) {
|
||||
scm_puts((char *) "#<swig ", port);
|
||||
scm_puts((char *) "#<", port);
|
||||
scm_puts(attribute, port);
|
||||
scm_puts("swig ", port);
|
||||
if (type->str != NULL)
|
||||
scm_puts(type->str, port);
|
||||
else
|
||||
|
|
@ -179,32 +215,29 @@ print_swig (SCM swig_smob, SCM port, scm_print_state *pstate)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
if (type) {
|
||||
scm_puts((char *) "#<collected swig ", port);
|
||||
if (type->str != NULL)
|
||||
scm_puts(type->str, port);
|
||||
else
|
||||
scm_puts(type->name, port);
|
||||
scm_puts((char *) " ", port);
|
||||
scm_intprint((long) SCM_CELL_WORD_1(swig_smob), 16, port);
|
||||
scm_puts((char *) ">", port);
|
||||
/* non-zero means success */
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
print_collectable_swig (SCM swig_smob, SCM port, scm_print_state *pstate)
|
||||
{
|
||||
return print_swig_aux(swig_smob, port, pstate, "collectable ");
|
||||
}
|
||||
|
||||
static int
|
||||
print_destroyed_swig (SCM swig_smob, SCM port, scm_print_state *pstate)
|
||||
{
|
||||
return print_swig_aux(swig_smob, port, pstate, "destroyed ");
|
||||
}
|
||||
|
||||
static SCM
|
||||
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))
|
||||
return SCM_BOOL_T;
|
||||
else return SCM_BOOL_F;
|
||||
|
|
@ -230,16 +263,22 @@ SWIG_Guile_Init ()
|
|||
scm_set_smob_equalp(swig_tag, equalp_swig);
|
||||
}
|
||||
|
||||
if (!swig_collected_tag) {
|
||||
swig_collected_tag = scm_make_smob_type((char*)"collected swig", 0);
|
||||
scm_set_smob_print(swig_collected_tag, print_collected_swig);
|
||||
scm_set_smob_equalp(swig_collected_tag, equalp_swig);
|
||||
scm_set_smob_free(swig_collected_tag, free_swig);
|
||||
if (!swig_collectable_tag) {
|
||||
swig_collectable_tag = scm_make_smob_type((char*)"collectable swig", 0);
|
||||
scm_set_smob_print(swig_collectable_tag, print_collectable_swig);
|
||||
scm_set_smob_equalp(swig_collectable_tag, equalp_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(
|
||||
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"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* 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$
|
||||
*/
|
||||
|
|
@ -17,6 +17,15 @@
|
|||
The address of a variable containing this pointer will be
|
||||
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)
|
||||
|
||||
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
|
||||
to deal with multiple values.)
|
||||
|
||||
func(int **OUTPUT_NONCOLLECTABLE)
|
||||
|
||||
Likewise, but make the pointer object not garbage collectable.
|
||||
|
||||
func(int **BOTH)
|
||||
func(int **INOUT)
|
||||
|
||||
|
|
@ -42,12 +55,34 @@
|
|||
$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;";
|
||||
|
||||
%typemap(argout, doc="<" #SCM_TYPE ">") PTRTYPE *OUTPUT
|
||||
"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(argout) PTRTYPE *BOTH = PTRTYPE *OUTPUT;
|
||||
%typemap(in) PTRTYPE *INOUT = PTRTYPE *INPUT;
|
||||
|
|
|
|||
|
|
@ -3,31 +3,6 @@
|
|||
|
||||
$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 */
|
||||
|
||||
%typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] {
|
||||
|
|
@ -80,6 +55,23 @@
|
|||
$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 */
|
||||
|
||||
%typemap(in) SWIGTYPE($&1_ltype argp) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue