fix memory corruption/segfault in the argout typemap when it is used with a wrapped pointer return
  unsigned long typemaps could overflow... correctly check for this case


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@7674 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
John Lenz 2005-10-18 04:05:11 +00:00
commit 16d7a306b8
6 changed files with 123 additions and 122 deletions

View file

@ -515,7 +515,7 @@ all the modules.</p>
that type. The destructor and delete functions are no longer exported for
use in scheme code, instead SWIG and chicken manage pointers.
In situations where SWIG knows that a function is returning a type that should
be garbage collected, SWIG will automaticly set the owner flag to 1. For other functions,
be garbage collected, SWIG will automatically set the owner flag to 1. For other functions,
the <code>%newobject</code> directive must be specified for functions whose return values
should be garbage collected. See
<a href="Customization.html#ownership">Object ownership and %newobject</a> for more information.

View file

@ -10,7 +10,7 @@ PROXYSUFFIX = _runme_proxy.ss
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CHICKEN_CSI = @CHICKEN_CSI@ -quiet
CHICKEN_CSI = @CHICKEN_CSI@ -quiet -batch -no-init
SO = @SO@
#C_TEST_CASES = long_long list_vector pointer_in_out multivalue

View file

@ -134,10 +134,10 @@ SIMPLE_TYPEMAP(int, C_num_to_int, C_fix, C_swig_is_number, (int), 0);
SIMPLE_TYPEMAP(short, C_num_to_int, C_fix, C_swig_is_number, (int), 0);
SIMPLE_TYPEMAP(long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
SIMPLE_TYPEMAP(long long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
SIMPLE_TYPEMAP(unsigned int, C_num_to_unsigned_int, C_fix, C_swig_is_number, (int), 0);
SIMPLE_TYPEMAP(unsigned short, C_num_to_unsigned_int, C_fix, C_swig_is_number, (int), 0);
SIMPLE_TYPEMAP(unsigned long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
SIMPLE_TYPEMAP(unsigned long long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
SIMPLE_TYPEMAP(unsigned int, C_num_to_unsigned_int, C_unsigned_int_to_num, C_swig_is_number, (unsigned int), C_SIZEOF_FLONUM);
SIMPLE_TYPEMAP(unsigned short, C_num_to_unsigned_int, C_fix, C_swig_is_number, (unsigned int), 0);
SIMPLE_TYPEMAP(unsigned long, C_num_to_unsigned_long, C_unsigned_long_to_num, C_swig_is_long, (unsigned long), C_SIZEOF_FLONUM);
SIMPLE_TYPEMAP(unsigned long long, C_num_to_unsigned_long, C_unsigned_long_to_num, C_swig_is_long, (unsigned long), C_SIZEOF_FLONUM);
SIMPLE_TYPEMAP(unsigned char, C_character_code, C_make_character, C_swig_is_char, (unsigned int), 0);
SIMPLE_TYPEMAP(signed char, C_character_code, C_make_character, C_swig_is_char, (int), 0);
SIMPLE_TYPEMAP(char, C_character_code, C_make_character, C_swig_is_char, (char), 0);
@ -190,11 +190,11 @@ SIMPLE_TYPEMAP(double, C_c_double, C_flonum, C_swig_is_number, (double), C_SIZEO
$1 = SWIG_MustGetPtr($input, NULL, $argnum, 0);
}
%typemap(varin) SWIGTYPE * {
%typemap(varin,closcode="(slot-ref $input 'swig-this)") SWIGTYPE * {
$1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, 1, SWIG_POINTER_DISOWN);
}
%typemap(varin) SWIGTYPE & {
%typemap(varin,closcode="(slot-ref $input 'swig-this)") SWIGTYPE & {
$1 = *(($1_ltype)SWIG_MustGetPtr($input, $descriptor, 1, 0));
}
@ -215,25 +215,25 @@ SIMPLE_TYPEMAP(double, C_c_double, C_flonum, C_swig_is_number, (double), C_SIZEO
$1 = SWIG_MustGetPtr($input, NULL, 1, 0);
}
%typemap(out,chickenfastproxy="1") SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] {
%typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] {
C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
$result = SWIG_NewPointerObjProxy($1, $descriptor, $owner, $proxy);
$result = SWIG_NewPointerObj($1, $descriptor, $owner);
}
%typemap(out,chickenfastproxy="1") SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC {
%typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC {
C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor,(void **) &$1);
$result = SWIG_NewPointerObjProxy($1, ty, $owner, $proxy);
$result = SWIG_NewPointerObj($1, ty, $owner);
}
%typemap(varout,chickenfastproxy="1") SWIGTYPE *, SWIGTYPE [] {
%typemap(varout) SWIGTYPE *, SWIGTYPE [] {
C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
$result = SWIG_NewPointerObjProxy($varname, $descriptor, 0, 0);
$result = SWIG_NewPointerObj($varname, $descriptor, 0);
}
%typemap(varout,chickenfastproxy="1") SWIGTYPE & {
%typemap(varout) SWIGTYPE & {
C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
$result = SWIG_NewPointerObjProxy((void *) &$varname, $1_descriptor, 0, 0);
$result = SWIG_NewPointerObj((void *) &$varname, $1_descriptor, 0);
}
/* Pass-by-value */
@ -243,19 +243,19 @@ SIMPLE_TYPEMAP(double, C_c_double, C_flonum, C_swig_is_number, (double), C_SIZEO
$1 = *argp;
}
%typemap(varin) SWIGTYPE {
%typemap(varin,closcode="(slot-ref $input 'swig-this)") SWIGTYPE {
$&1_ltype argp;
argp = ($&1_ltype)SWIG_MustGetPtr($input, $&1_descriptor, 1, 0);
$1 = *argp;
}
%typemap(out,chickenfastproxy="1") SWIGTYPE
%typemap(out) SWIGTYPE
#ifdef __cplusplus
{
$&1_ltype resultptr;
C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
resultptr = new $1_ltype(($1_ltype &) $1);
$result = SWIG_NewPointerObjProxy(resultptr, $&1_descriptor, 1, $proxy);
$result = SWIG_NewPointerObj(resultptr, $&1_descriptor, 1);
}
#else
{
@ -263,17 +263,17 @@ SIMPLE_TYPEMAP(double, C_c_double, C_flonum, C_swig_is_number, (double), C_SIZEO
C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
resultptr = ($&1_ltype) malloc(sizeof($1_type));
memmove(resultptr, &$1, sizeof($1_type));
$result = SWIG_NewPointerObjProxy(resultptr, $&1_descriptor, 1,$proxy);
$result = SWIG_NewPointerObj(resultptr, $&1_descriptor, 1);
}
#endif
%typemap(varout,chickenfastproxy="1") SWIGTYPE
%typemap(varout) SWIGTYPE
#ifdef __cplusplus
{
$&1_ltype resultptr;
C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
resultptr = new $1_ltype(($1_ltype&) $1);
$result = SWIG_NewPointerObjProxy(resultptr, $&1_descriptor, 0, 0);
$result = SWIG_NewPointerObj(resultptr, $&1_descriptor, 0);
}
#else
{
@ -281,7 +281,7 @@ SIMPLE_TYPEMAP(double, C_c_double, C_flonum, C_swig_is_number, (double), C_SIZEO
C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
resultptr = ($&1_ltype) malloc(sizeof($1_type));
memmove(resultptr, &$1, sizeof($1_type));
$result = SWIG_NewPointerObjProxy(resultptr, $&1_descriptor, 0, 0);
$result = SWIG_NewPointerObj(resultptr, $&1_descriptor, 0);
}
#endif

View file

@ -2,7 +2,7 @@
* -----------------------------------------------------------------------
* swig_lib/chicken/chickenrun.swg
*
* Author: John Lenz <jelenz@wisc.edu>
* Author: John Lenz <lenz@cs.wisc.edu>
* ----------------------------------------------------------------------- */
#include <chicken.h>
@ -25,9 +25,7 @@ extern "C" {
#define SWIG_MustGetPtr(s, type, argnum, flags) \
SWIG_Chicken_MustGetPtr(s, type, argnum, flags)
#define SWIG_NewPointerObj(ptr, type, owner) \
SWIG_Chicken_NewPointerObj((void*)ptr, type, owner, 1, &known_space)
#define SWIG_NewPointerObjProxy(ptr, type, owner, proxy) \
SWIG_Chicken_NewPointerObj((void*)ptr, type, owner, proxy, &known_space)
SWIG_Chicken_NewPointerObj((void*)ptr, type, owner, &known_space)
#define swig_barf SWIG_Chicken_Barf
#define SWIG_ThrowException(val) SWIG_Chicken_ThrowException(val)
@ -52,33 +50,38 @@ extern "C" {
#define C_swig_is_number(x) (C_swig_is_fixnum(x) || C_swig_is_flonum(x))
#define C_swig_is_long(x) C_swig_is_number(x)
#define SWIG_APPEND_VALUE(object) \
if (resultobj == C_SCHEME_UNDEFINED) \
resultobj = object; \
else { \
C_word *pair_space = C_alloc(C_SIZEOF_PAIR); \
if (!gswig_list_p) { \
gswig_list_p = 1; \
C_word *pair_space2 = C_alloc(C_SIZEOF_PAIR); \
resultobj = C_pair(&pair_space2, resultobj, C_SCHEME_END_OF_LIST); \
resultobjlast = resultobj; \
} \
C_word tmp = C_pair(&pair_space, object, C_SCHEME_END_OF_LIST); \
C_set_block_item(resultobjlast, 1, tmp); \
resultobjlast = tmp; \
#define C_swig_sizeof_closure(num) (num+1)
#define SWIG_Chicken_SetupArgout { \
C_word *a = C_alloc(C_swig_sizeof_closure(2)); \
C_word *closure = a; \
*(a++)=C_CLOSURE_TYPE|2; \
*(a++)=(C_word)SWIG_Chicken_ApplyResults; \
*(a++)=continuation; \
continuation=(C_word)closure; \
}
#define SWIG_APPEND_VALUE(obj) \
if (obj != C_SCHEME_UNDEFINED) { \
C_word *a = C_alloc(C_swig_sizeof_closure(3)); \
C_word *closure = a; \
*(a++)=C_CLOSURE_TYPE|3; \
*(a++)=(C_word)SWIG_Chicken_MultiResultBuild; \
*(a++)=(C_word)continuation; \
*(a++)=(C_word)(obj); \
continuation=(C_word)closure; \
}
/* given a SWIG pointer wrapped in a C_word, return the proxy create function, if any */
#define SWIG_Chicken_FindCreateProxy(val, x) \
if (C_swig_is_swigpointer(x)) { \
swig_type_info *t = (swig_type_info *) C_block_item(x, 1); \
#define SWIG_Chicken_FindCreateProxy(func,obj) \
if (C_swig_is_swigpointer(obj)) { \
swig_type_info *t = (swig_type_info *) C_block_item(obj, 1); \
if (t && t->clientdata && ((swig_chicken_clientdata *)t->clientdata)->gc_proxy_create) { \
val = CHICKEN_gc_root_ref( ((swig_chicken_clientdata *)t->clientdata)->gc_proxy_create); \
func = CHICKEN_gc_root_ref( ((swig_chicken_clientdata *)t->clientdata)->gc_proxy_create); \
} else { \
val = C_SCHEME_FALSE; \
func = C_SCHEME_FALSE; \
} \
} else { \
val = C_SCHEME_FALSE; \
func = C_SCHEME_FALSE; \
}
#define SWIG_POINTER_DISOWN 1
@ -232,7 +235,7 @@ SWIG_Chicken_Finalizer(C_word argc, C_word closure, C_word continuation, C_word
static C_word finalizer_obj[2] = {(C_word) (C_CLOSURE_TYPE|1), (C_word) SWIG_Chicken_Finalizer};
static C_word
SWIG_Chicken_NewPointerObj(void *ptr, swig_type_info *type, int owner, int create_proxy, C_word **data)
SWIG_Chicken_NewPointerObj(void *ptr, swig_type_info *type, int owner, C_word **data)
{
swig_chicken_clientdata *cdata = (swig_chicken_clientdata *) type->clientdata;
@ -246,14 +249,6 @@ SWIG_Chicken_NewPointerObj(void *ptr, swig_type_info *type, int owner, int creat
C_do_register_finalizer(cptr, (C_word) finalizer_obj);
#endif
/* wrap the result inside a proxy class if one is available */
if (create_proxy && cdata && cdata->gc_proxy_create) {
C_word closure = CHICKEN_gc_root_ref(cdata->gc_proxy_create);
if (C_swig_is_closurep(closure)) {
C_save(cptr);
return C_callback(closure, 1);
}
}
return cptr;
}
}
@ -348,6 +343,25 @@ SWIG_Chicken_SetModule(swig_module_info *module) {
C_set_block_item(sym, 0, pointer);
}
static C_word SWIG_Chicken_MultiResultBuild(C_word num, C_word closure, C_word lst) {
C_word cont = C_block_item(closure,1);
C_word obj = C_block_item(closure,2);
C_word func;
SWIG_Chicken_FindCreateProxy(func,obj);
if (C_swig_is_closurep(func)) {
((C_proc3)(void *)C_block_item(func, 0))(4,func,cont,obj,lst);
} else {
C_word *a = C_alloc(C_SIZEOF_PAIR);
C_kontinue(cont,C_pair(&a,obj,lst));
}
}
C_word SWIG_Chicken_ApplyResults(C_word num, C_word closure, C_word result) {
C_apply_values(3,C_SCHEME_UNDEFINED,C_block_item(closure,1),result);
}
#ifdef __cplusplus
}
#endif

View file

@ -105,9 +105,6 @@ or you can use the %apply directive :
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
The CHICKEN output of the function would be a list containing both
output values, in reverse order.
*/
// These typemaps contributed by Robin Dunn
@ -168,10 +165,10 @@ INOUT_TYPEMAP(enum SWIGTYPE, C_num_to_int, C_fix, C_swig_is_number, (int), 0);
INOUT_TYPEMAP(short, C_num_to_int, C_fix, C_swig_is_number, (int), 0);
INOUT_TYPEMAP(long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
INOUT_TYPEMAP(long long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
INOUT_TYPEMAP(unsigned int, C_num_to_unsigned_int, C_fix, C_swig_is_number, (int), 0);
INOUT_TYPEMAP(unsigned short, C_num_to_unsigned_int, C_fix, C_swig_is_number, (int), 0);
INOUT_TYPEMAP(unsigned long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
INOUT_TYPEMAP(unsigned long long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
INOUT_TYPEMAP(unsigned int, C_num_to_unsigned_int, C_unsigned_int_to_num, C_swig_is_number, (int), C_SIZEOF_FLONUM);
INOUT_TYPEMAP(unsigned short, C_num_to_unsigned_int, C_fix, C_swig_is_number, (unsigned int), 0);
INOUT_TYPEMAP(unsigned long, C_num_to_unsigned_long, C_unsigned_long_to_num, C_swig_is_long, (unsigned long), C_SIZEOF_FLONUM);
INOUT_TYPEMAP(unsigned long long, C_num_to_unsigned_long, C_unsigned_long_to_num, C_swig_is_long, (unsigned long), C_SIZEOF_FLONUM);
INOUT_TYPEMAP(unsigned char, C_character_code, C_make_character, C_swig_is_char, (unsigned int), 0);
INOUT_TYPEMAP(signed char, C_character_code, C_make_character, C_swig_is_char, (int), 0);
INOUT_TYPEMAP(char, C_character_code, C_make_character, C_swig_is_char, (char), 0);

View file

@ -357,10 +357,10 @@ CHICKEN::functionWrapper(Node *n)
String *scmname;
bool any_specialized_arg = false;
List *function_arg_types = NewList();
int return_proxy_fastcall = 0;
int num_required;
int num_arguments;
int have_argout;
Printf(mangle, "\"%s\"", SwigType_manglestr(d));
@ -529,12 +529,16 @@ CHICKEN::functionWrapper(Node *n)
emit_action(n,f);
/* Insert argument output code */
have_argout = 0;
for (p = l; p;) {
if ((tm = Getattr(p,"tmap:argout"))) {
if (!Wrapper_check_local(f, "gswig_list_p")) {
Wrapper_add_local(f,"resultobjlast", "C_word resultobjlast");
Wrapper_add_local(f,"gswig_list_p", "int gswig_list_p = 0");
if (!have_argout) {
have_argout = 1;
// Print initial argument output code
Printf(f->code,"SWIG_Chicken_SetupArgout\n");
}
Replaceall(tm,"$source",Getattr(p,"lname"));
Replaceall(tm,"$target","resultobj");
Replaceall(tm,"$arg",Getattr(p,"emit:input"));
@ -557,22 +561,11 @@ CHICKEN::functionWrapper(Node *n)
Replaceall(tm,"$owner","0");
}
/* check for chickenfastproxy flag */
if (Getattr(n, "tmap:out:chickenfastproxy")) {
if (exporting_constructor && clos && hide_primitive) {
/* Don't return a proxy, the wrapped CLOS class is the proxy */
Replaceall(tm, "$proxy", "0");
} else {
/* can only do fast proxy if there are no argout paramaters... */
if (Wrapper_check_local(f, "gswig_list_p")) {
Replaceall(tm, "$proxy", "1");
} else {
Replaceall(tm, "$proxy", "0");
return_proxy_fastcall = 1;
}
}
}
Printf(f->code, "%s", tm);
if (have_argout)
Printf(f->code, "\nSWIG_APPEND_VALUE(resultobj);\n");
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
"Unable to use return type %s in function %s.\n",
@ -599,22 +592,24 @@ CHICKEN::functionWrapper(Node *n)
Printf(f->code,"%s\n",tm);
}
if (return_proxy_fastcall) {
Printv(f->code,"{\n",
if (have_argout) {
Printf(f->code, "C_kontinue(continuation,C_SCHEME_END_OF_LIST);\n");
} else {
if (exporting_constructor && clos && hide_primitive) {
/* Don't return a proxy, the wrapped CLOS class is the proxy */
Printf(f->code, "C_kontinue(continuation,resultobj);\n");
} else {
// make the continuation the proxy creation function, if one exists
Printv(f->code,"{\n",
"C_word func;\n",
"SWIG_Chicken_FindCreateProxy(func, resultobj);\n",
"SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
"if (C_swig_is_closurep(func))\n",
" ((C_proc3)(void *)C_block_item(func, 0))(3,func,continuation,resultobj);\n",
" ((C_proc3)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
"else\n",
" C_kontinue(continuation, resultobj);\n",
"}\n", NIL);
} else if (Wrapper_check_local(f, "gswig_list_p")) {
Printv(f->code,"if (gswig_list_p)\n",
" C_apply_values(3, C_SCHEME_UNDEFINED, continuation, resultobj);\n",
"else\n",
" C_kontinue(continuation, resultobj);\n", NIL);
} else {
Printf(f->code,"C_kontinue (continuation, resultobj);\n");
}
}
/* Error handling code */
@ -808,18 +803,14 @@ CHICKEN::variableWrapper(Node *n) {
"Unable to read variable of type %s\n", SwigType_str(t,0));
}
if (Getattr(n, "tmap:varout:chickenfastproxy")) {
Printv(f->code,"{\n",
"C_word func;\n",
"SWIG_Chicken_FindCreateProxy(func, resultobj);\n",
"if (C_swig_is_closurep(func))\n",
" ((C_proc3)(void *)C_block_item(func, 0))(3,func,continuation,resultobj);\n",
"else\n",
" C_kontinue(continuation, resultobj);\n",
"}\n", NIL);
} else {
Printf(f->code," C_kontinue (continuation, resultobj);\n");
}
Printv(f->code,"{\n",
"C_word func;\n",
"SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
"if (C_swig_is_closurep(func))\n",
" ((C_proc3)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
"else\n",
" C_kontinue(continuation, resultobj);\n",
"}\n", NIL);
/* Error handling code */
#ifdef USE_FAIL
@ -842,9 +833,11 @@ CHICKEN::variableWrapper(Node *n) {
clos_name = chickenNameMapping(scmname, (char *)"");
Node *class_node = classLookup(t);
if (class_node && Getattr(n, "tmap:varout:chickenfastproxy")) {
String *clos_code = Getattr(n, "tmap:varin:closcode");
if (class_node && clos_code) {
Replaceall(clos_code,"$input", "(car lst)");
Printv(clos_methods, "(define (", clos_name, " . lst) (if (null? lst) (", chickenPrimitiveName(scmname), ") (",
chickenPrimitiveName(scmname), " (slot-ref (car lst) 'swig-this))))\n", NIL);
chickenPrimitiveName(scmname), " ", clos_code, ")))\n", NIL);
} else {
/* Simply re-export the procedure */
Printv(clos_methods, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")\n", NIL);
@ -996,18 +989,14 @@ CHICKEN::constantWrapper(Node *n)
"Unable to read variable of type %s\n", SwigType_str(t,0));
}
if (Getattr(n, "tmap:varout:chickenfastproxy")) {
Printv(f->code,"{\n",
"C_word func;\n",
"SWIG_Chicken_FindCreateProxy(func, resultobj);\n",
"if (C_swig_is_closurep(func))\n",
" ((C_proc3)(void *)C_block_item(func, 0))(3,func,continuation,resultobj);\n",
"else\n",
" C_kontinue(continuation, resultobj);\n",
"}\n", NIL);
} else {
Printf(f->code," C_kontinue (continuation, resultobj);\n");
}
Printv(f->code,"{\n",
"C_word func;\n",
"SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
"if (C_swig_is_closurep(func))\n",
" ((C_proc3)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
"else\n",
" C_kontinue(continuation, resultobj);\n",
"}\n", NIL);
/* Error handling code */
#ifdef USE_FAIL
@ -1163,8 +1152,9 @@ CHICKEN::classHandler(Node *n)
"}\n", NIL);
addMethod(closfuncname, funcname);
Printv(clos_methods, "(", chickenPrimitiveName(closfuncname), " (lambda (x) (make ", class_name, " 'swig-this x)))\n\n", NIL);
Printv(clos_methods, "(", chickenPrimitiveName(closfuncname), " (lambda (x lst) (if lst ",
"(cons (make ", class_name, " 'swig-this x) lst) ",
"(make ", class_name, " 'swig-this x))))\n\n", NIL);
Delete(closfuncname);
Delete(funcname);
}