Now passes regressions with '-O -builtin'. Almost all changes

are to accomodate -fastunpack.



git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/szager-python-builtin@12423 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Stefan Zager 2011-02-02 10:28:46 +00:00
commit 00b5fa9c47
2 changed files with 190 additions and 63 deletions

View file

@ -108,6 +108,16 @@ wrapper##_closure (PyObject *a, Py_ssize_t b) \
return result; \ return result; \
} }
#define PYSWIG_FUNPACK_SSIZEARGFUNC_CLOSURE(wrapper) \
SWIGINTERN PyObject* \
wrapper##_closure (PyObject *a, Py_ssize_t b) \
{ \
PyObject *arg = _PyLong_FromSsize_t(b); \
PyObject *result = wrapper(a, arg); \
Py_DECREF(arg); \
return result; \
}
#define PYSWIG_SSIZEOBJARGPROC_CLOSURE(wrapper) \ #define PYSWIG_SSIZEOBJARGPROC_CLOSURE(wrapper) \
SWIGINTERN int \ SWIGINTERN int \
wrapper##_closure (PyObject *a, Py_ssize_t b, PyObject *c) \ wrapper##_closure (PyObject *a, Py_ssize_t b, PyObject *c) \
@ -179,6 +189,18 @@ pyswig_getter_closure (PyObject *obj, void *closure)
return result; return result;
} }
SWIGRUNTIME PyObject*
pyswig_funpack_getter_closure (PyObject *obj, void *closure)
{
if (!closure)
return SWIG_Py_Void();
SwigPyGetSet *getset = (SwigPyGetSet*) closure;
if (!getset->get)
return SWIG_Py_Void();
PyObject *result = (*getset->get)(obj, NULL);
return result;
}
SWIGRUNTIME int SWIGRUNTIME int
pyswig_setter_closure (PyObject *obj, PyObject *val, void *closure) pyswig_setter_closure (PyObject *obj, PyObject *val, void *closure)
{ {
@ -201,6 +223,23 @@ pyswig_setter_closure (PyObject *obj, PyObject *val, void *closure)
return result ? 0 : -1; return result ? 0 : -1;
} }
SWIGRUNTIME int
pyswig_funpack_setter_closure (PyObject *obj, PyObject *val, void *closure)
{
if (!closure) {
PyErr_Format(PyExc_TypeError, "Missing getset closure");
return -1;
}
SwigPyGetSet *getset = (SwigPyGetSet*) closure;
if (!getset->set) {
PyErr_Format(PyExc_TypeError, "Illegal member variable assignment in type '%.300s'", obj->ob_type->tp_name);
return -1;
}
PyObject *result = (*getset->set)(obj, val);
Py_XDECREF(result);
return result ? 0 : -1;
}
SWIGRUNTIME PyObject* SWIGRUNTIME PyObject*
pyswig_static_getter_closure (PyObject *obj, void *closure) pyswig_static_getter_closure (PyObject *obj, void *closure)
{ {

View file

@ -170,7 +170,7 @@ static String *getSlot(Node *n, const char *key) {
return val ? val : slot_default; return val ? val : slot_default;
} }
static String *getClosure(String *functype, String *wrapper) { static String *getClosure(String *functype, String *wrapper, int funpack = 0) {
static const char *functypes[] = { static const char *functypes[] = {
"unaryfunc", "PYSWIG_UNARYFUNC_CLOSURE", "unaryfunc", "PYSWIG_UNARYFUNC_CLOSURE",
"destructor", "PYSWIG_DESTRUCTOR_CLOSURE", "destructor", "PYSWIG_DESTRUCTOR_CLOSURE",
@ -188,13 +188,36 @@ static String *getClosure(String *functype, String *wrapper) {
NULL NULL
}; };
static const char *funpack_functypes[] = {
"unaryfunc", "PYSWIG_UNARYFUNC_CLOSURE",
"destructor", "PYSWIG_DESTRUCTOR_CLOSURE",
"inquiry", "PYSWIG_INQUIRY_CLOSURE",
"getiterfunc", "PYSWIG_UNARYFUNC_CLOSURE",
"iternextfunc", "PYSWIG_UNARYFUNC_CLOSURE",
"ternaryfunc", "PYSWIG_TERNARYFUNC_CLOSURE",
"lenfunc", "PYSWIG_LENFUNC_CLOSURE",
"ssizeargfunc", "PYSWIG_FUNPACK_SSIZEARGFUNC_CLOSURE",
"ssizessizeargfunc", "PYSWIG_SSIZESSIZEARGFUNC_CLOSURE",
"ssizeobjargproc", "PYSWIG_SSIZEOBJARGPROC_CLOSURE",
"ssizessizeobjargproc", "PYSWIG_SSIZESSIZEOBJARGPROC_CLOSURE",
"objobjargproc", "PYSWIG_OBJOBJARGPROC_CLOSURE",
NULL
};
if (!functype) if (!functype)
return NULL; return NULL;
char *c = Char(functype); char *c = Char(functype);
int i; int i;
for (i = 0; functypes[i] != NULL; i += 2) { if (funpack) {
if (!strcmp(c, functypes[i])) for (i = 0; funpack_functypes[i] != NULL; i += 2) {
return NewStringf("%s(%s)", functypes[i + 1], wrapper); if (!strcmp(c, funpack_functypes[i]))
return NewStringf("%s(%s)", funpack_functypes[i + 1], wrapper);
}
} else {
for (i = 0; functypes[i] != NULL; i += 2) {
if (!strcmp(c, functypes[i]))
return NewStringf("%s(%s)", functypes[i + 1], wrapper);
}
} }
return NULL; return NULL;
} }
@ -1784,9 +1807,19 @@ public:
* add_method() * add_method()
* ------------------------------------------------------------ */ * ------------------------------------------------------------ */
void add_method(String *name, String *function, int kw, Node *n = 0, int = 0, int = -1, int = -1) { void add_method(String *name, String *function, int kw, Node *n = 0, int funpack= 0, int num_required= -1, int num_arguments = -1) {
if (!kw) { if (!kw) {
Printf(methods, "\t { (char *)\"%s\", %s, METH_VARARGS, ", name, function); if (n && funpack) {
if (num_required == 0 && num_arguments == 0) {
Printf(methods, "\t { (char *)\"%s\", (PyCFunction)%s, METH_NOARGS, ", name, function);
} else if (num_required == 1 && num_arguments == 1) {
Printf(methods, "\t { (char *)\"%s\", (PyCFunction)%s, METH_O, ", name, function);
} else {
Printf(methods, "\t { (char *)\"%s\", %s, METH_VARARGS, ", name, function);
}
} else {
Printf(methods, "\t { (char *)\"%s\", %s, METH_VARARGS, ", name, function);
}
} else { } else {
Printf(methods, "\t { (char *)\"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS, ", name, function); Printf(methods, "\t { (char *)\"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS, ", name, function);
} }
@ -1819,9 +1852,11 @@ public:
/* ------------------------------------------------------------ /* ------------------------------------------------------------
* dispatchFunction() * dispatchFunction()
* ------------------------------------------------------------ */ * ------------------------------------------------------------ */
void dispatchFunction(Node *n, String *linkage, int funpack = 0, bool return_int = false, bool add_self = false, bool addmeth = true) { void dispatchFunction(Node *n, String *linkage, int funpack = 0, bool builtin_self = false, bool builtin_ctor = false, bool director_class = false) {
/* Last node in overloaded chain */ /* Last node in overloaded chain */
bool add_self = builtin_self && (!builtin_ctor || director_class);
int maxargs; int maxargs;
String *tmp = NewString(""); String *tmp = NewString("");
@ -1840,7 +1875,7 @@ public:
String *symname = Getattr(n, "sym:name"); String *symname = Getattr(n, "sym:name");
String *wname = Swig_name_wrapper(symname); String *wname = Swig_name_wrapper(symname);
Printv(f->def, linkage, return_int ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args) {", NIL); Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args) {", NIL);
Wrapper_add_local(f, "argc", "int argc"); Wrapper_add_local(f, "argc", "int argc");
Printf(tmp, "PyObject *argv[%d]", maxargs + 1); Printf(tmp, "PyObject *argv[%d]", maxargs + 1);
@ -1860,8 +1895,11 @@ public:
Append(f->code, "argc++;\n"); Append(f->code, "argc++;\n");
} else { } else {
String *iname = Getattr(n, "sym:name"); String *iname = Getattr(n, "sym:name");
Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args,\"%s\",0,%d,argv))) SWIG_fail;\n", iname, maxargs); Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args,\"%s\",0,%d,argv%s))) SWIG_fail;\n", iname, maxargs, add_self ? "+1" : "");
Append(f->code, "--argc;\n"); if (add_self)
Append(f->code, "argv[0] = self;\n");
else
Append(f->code, "--argc;\n");
} }
Replaceall(dispatch, "$args", "self,args"); Replaceall(dispatch, "$args", "self,args");
@ -1883,13 +1921,13 @@ public:
Append(f->code, "fail:\n"); Append(f->code, "fail:\n");
Printf(f->code, "SWIG_SetErrorMsg(PyExc_NotImplementedError," Printf(f->code, "SWIG_SetErrorMsg(PyExc_NotImplementedError,"
"\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes); "\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes);
Printf(f->code, "return %s;\n", return_int ? "-1" : "0"); Printf(f->code, "return %s;\n", builtin_ctor ? "-1" : "0");
Delete(protoTypes); Delete(protoTypes);
} }
Printv(f->code, "}\n", NIL); Printv(f->code, "}\n", NIL);
Wrapper_print(f, f_wrappers); Wrapper_print(f, f_wrappers);
Node *p = Getattr(n, "sym:previousSibling"); Node *p = Getattr(n, "sym:previousSibling");
if (addmeth) if (!builtin_self)
add_method(symname, wname, 0, p); add_method(symname, wname, 0, p);
/* Create a shadow for this function (if enabled and not in a member function) */ /* Create a shadow for this function (if enabled and not in a member function) */
@ -1906,6 +1944,24 @@ public:
* functionWrapper() * functionWrapper()
* ------------------------------------------------------------ */ * ------------------------------------------------------------ */
/*
A note about argument marshalling with built-in types.
There are three distinct cases for member (non-static) methods:
1) An ordinary member function. In this case, the first param in
the param list is 'this'. For builtin types, 'this' is taken from
the first argument to the wrapper (usually called 'self); it's not
extracted from the second argument (which is usually a tuple).
2) A constructor for a non-director class. In this case, the
param list doesn't contain an entry for 'this', but the first ('self')
argument to the wrapper *does* contain the newly-allocated,
uninitialized object.
3) A constructor for a director class. In this case, the param
list contains a 'self' param, which comes from the first argument
to the wrapper function.
*/
const char *get_implicitconv_flag(Node *klass) { const char *get_implicitconv_flag(Node *klass) {
int conv = 0; int conv = 0;
@ -1973,16 +2029,13 @@ public:
builtin_ctor = true; builtin_ctor = true;
} }
bool director_class = (getCurrentClass() && Swig_directorclass(getCurrentClass())); bool director_class = (getCurrentClass() && Swig_directorclass(getCurrentClass()));
bool add_self = builtin_self && (!builtin_ctor || director_class);
bool builtin_getter = (builtin && GetFlag(n, "memberget")); bool builtin_getter = (builtin && GetFlag(n, "memberget"));
bool builtin_setter = (builtin && GetFlag(n, "memberset") && !builtin_getter); bool builtin_setter = (builtin && GetFlag(n, "memberset") && !builtin_getter);
char const *self_param = builtin_self ? "self" : "SWIGUNUSEDPARM(self)"; char const *self_param = builtin_self ? "self" : "SWIGUNUSEDPARM(self)";
char const *wrap_return = builtin_ctor ? "int " : "PyObject *"; char const *wrap_return = builtin_ctor ? "int " : "PyObject *";
String *linkage = NewString("SWIGINTERN "); String *linkage = NewString("SWIGINTERN ");
String *wrapper_name = Swig_name_wrapper(iname); String *wrapper_name = Swig_name_wrapper(iname);
String *slot = Getattr(n, "feature:pyslot");
String *closure_decl = NULL;
if (slot)
closure_decl = getClosure(Getattr(n, "feature:pyslot:functype"), wrapper_name);
if (Getattr(n, "sym:overloaded")) { if (Getattr(n, "sym:overloaded")) {
overname = Getattr(n, "sym:overname"); overname = Getattr(n, "sym:overname");
@ -2016,7 +2069,7 @@ public:
/* Get number of required and total arguments */ /* Get number of required and total arguments */
tuple_arguments = num_arguments = emit_num_arguments(l); tuple_arguments = num_arguments = emit_num_arguments(l);
tuple_required = num_required = emit_num_required(l); tuple_required = num_required = emit_num_required(l);
if (builtin_self && (!builtin_ctor || (builtin_ctor && director_class))) { if (add_self) {
--tuple_arguments; --tuple_arguments;
--tuple_required; --tuple_required;
} }
@ -2029,7 +2082,7 @@ public:
Append(wname, overname); Append(wname, overname);
} }
if (!allow_kwargs || Getattr(n, "sym:overloaded")) { if (!allow_kwargs || overname) {
if (!varargs) { if (!varargs) {
Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL); Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL);
} else { } else {
@ -2056,8 +2109,15 @@ public:
} }
int funpack = modernargs && fastunpack && !varargs && !allow_kwargs; int funpack = modernargs && fastunpack && !varargs && !allow_kwargs;
int noargs = funpack && (num_required == 0 && num_arguments == 0); int noargs = funpack && (tuple_required == 0 && tuple_arguments == 0);
int onearg = funpack && (num_required == 1 && num_arguments == 1); int onearg = funpack && (tuple_required == 1 && tuple_arguments == 1);
if (builtin && funpack && !overname && !builtin_ctor) {
if (noargs)
SetFlag(n, "noargs");
else if (onearg)
SetFlag(n, "onearg");
}
/* Generate code for argument marshalling */ /* Generate code for argument marshalling */
if (funpack) { if (funpack) {
@ -2093,16 +2153,10 @@ public:
Delete(tmp_none_comparison); Delete(tmp_none_comparison);
} }
if (builtin_self && !builtin_ctor)
Printf(self_parse, "%s = self;\n", funpack ? "swig_obj[0]" : "obj0");
if (builtin_ctor && director_class)
Printv(self_parse, funpack ? "swig_obj[1]" : "obj1", " = self;\n", NIL);
int use_parse = 0; int use_parse = 0;
Append(kwargs, "{"); Append(kwargs, "{");
for (i = 0, p = l; i < num_arguments; i++) { for (i = 0, p = l; i < num_arguments; i++) {
bool parse_from_tuple = (i > 0 || !builtin_self || (builtin_ctor && !director_class)); bool parse_from_tuple = (i > 0 || !add_self);
while (checkAttribute(p, "tmap:in:numinputs", "0")) { while (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next"); p = Getattr(p, "tmap:in:next");
} }
@ -2110,8 +2164,10 @@ public:
SwigType *pt = Getattr(p, "type"); SwigType *pt = Getattr(p, "type");
String *pn = Getattr(p, "name"); String *pn = Getattr(p, "name");
String *ln = Getattr(p, "lname"); String *ln = Getattr(p, "lname");
if (funpack) if (!parse_from_tuple)
sprintf(source, "swig_obj[%d]", builtin_ctor ? i + 1 : i); sprintf(source, "self");
else if (funpack)
sprintf(source, "swig_obj[%d]", add_self && !overname ? i - 1 : i);
else else
sprintf(source, "obj%d", builtin_ctor ? i + 1 : i); sprintf(source, "obj%d", builtin_ctor ? i + 1 : i);
@ -2141,7 +2197,9 @@ public:
if ((tm = Getattr(p, "tmap:in"))) { if ((tm = Getattr(p, "tmap:in"))) {
String *parse = Getattr(p, "tmap:in:parse"); String *parse = Getattr(p, "tmap:in:parse");
if (!parse) { if (!parse) {
if (funpack) { if (builtin_self) {
Replaceall(tm, "$self", "self");
} else if (funpack) {
Replaceall(tm, "$self", "swig_obj[0]"); Replaceall(tm, "$self", "swig_obj[0]");
} else { } else {
Replaceall(tm, "$self", "obj0"); Replaceall(tm, "$self", "obj0");
@ -2167,14 +2225,11 @@ public:
Setattr(p, "implicitconv", convflag); Setattr(p, "implicitconv", convflag);
} }
bool parse_from_tuple = (i > 0 || !builtin_self || (builtin_ctor && !director_class));
if (parse_from_tuple) if (parse_from_tuple)
Putc('O', parse_args); Putc('O', parse_args);
if (!funpack) { if (!funpack && parse_from_tuple) {
Wrapper_add_localv(f, source, "PyObject *", source, "= 0", NIL); Wrapper_add_localv(f, source, "PyObject *", source, "= 0", NIL);
if (parse_from_tuple) Printf(arglist, "&%s", source);
Printf(arglist, "&%s", source);
} }
if (i >= num_required) if (i >= num_required)
Printv(get_pointers, "if (", source, ") {\n", NIL); Printv(get_pointers, "if (", source, ") {\n", NIL);
@ -2227,13 +2282,13 @@ public:
} else { } else {
Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL); Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL);
} }
if (onearg) { if (onearg && !builtin_ctor) {
Printf(parse_args, "if (!args) SWIG_fail;\n"); Printf(parse_args, "if (!args) SWIG_fail;\n");
Printf(parse_args, "swig_obj[0] = args;\n"); Append(parse_args, "swig_obj[0] = args;\n");
} else if (!noargs) { } else if (!noargs) {
Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args,\"%s\",%d,%d,swig_obj)) SWIG_fail;\n", iname, num_required, num_arguments); Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args,\"%s\",%d,%d,swig_obj)) SWIG_fail;\n", iname, tuple_required, tuple_arguments);
} else if (noargs) { } else if (noargs) {
Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args,\"%s\",%d,%d,0)) SWIG_fail;\n", iname, num_required, num_arguments); Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args,\"%s\",%d,%d,0)) SWIG_fail;\n", iname, tuple_required, tuple_arguments);
} }
} }
} else if (tuple_arguments > 0) { } else if (tuple_arguments > 0) {
@ -2334,9 +2389,11 @@ public:
} }
Wrapper_add_local(f, "upcall", "bool upcall = false"); Wrapper_add_local(f, "upcall", "bool upcall = false");
if (funpack) { if (funpack) {
Append(f->code, "upcall = (director && (director->swig_get_self()==swig_obj[0]));\n"); const char *self_parm = builtin_self ? "self" : "swig_obj[0]";
Printf(f->code, "upcall = (director && (director->swig_get_self()==%s));\n", self_parm);
} else { } else {
Append(f->code, "upcall = (director && (director->swig_get_self()==obj0));\n"); const char *self_parm = builtin_self ? "self" : "obj0";
Printf(f->code, "upcall = (director && (director->swig_get_self()==%s));\n", self_parm);
} }
} }
@ -2377,7 +2434,9 @@ public:
} }
if (tm) { if (tm) {
if (funpack) { if (builtin_self) {
Replaceall(tm, "$self", "self");
} else if (funpack) {
Replaceall(tm, "$self", "swig_obj[0]"); Replaceall(tm, "$self", "swig_obj[0]");
} else { } else {
Replaceall(tm, "$self", "obj0"); Replaceall(tm, "$self", "obj0");
@ -2501,7 +2560,9 @@ public:
Replaceall(f->code, "$symname", iname); Replaceall(f->code, "$symname", iname);
Replaceall(f->code, "$result", "resultobj"); Replaceall(f->code, "$result", "resultobj");
if (funpack) { if (builtin_self) {
Replaceall(f->code, "$self", "self");
} else if (funpack) {
Replaceall(f->code, "$self", "swig_obj[0]"); Replaceall(f->code, "$self", "swig_obj[0]");
} else { } else {
Replaceall(f->code, "$self", "obj0"); Replaceall(f->code, "$self", "obj0");
@ -2539,9 +2600,7 @@ public:
} }
} else { } else {
if (!Getattr(n, "sym:nextSibling")) { if (!Getattr(n, "sym:nextSibling")) {
dispatchFunction(n, linkage, funpack, builtin_ctor, // return_int dispatchFunction(n, linkage, funpack, builtin_self, builtin_ctor, director_class);
builtin_self && (!builtin_ctor || director_class), // add_self
!builtin_self); // addmeth
} }
} }
@ -2579,13 +2638,16 @@ public:
} }
/* Handle builtin operator overloads */ /* Handle builtin operator overloads */
String *slot = Getattr(n, "feature:pyslot");
if (slot) { if (slot) {
String *closure_decl = getClosure(Getattr(n, "feature:pyslot:functype"), wrapper_name, overname ? 0 : funpack);
String *feature_name = NewStringf("feature:%s", slot); String *feature_name = NewStringf("feature:%s", slot);
String *closure_name = Copy(wrapper_name); String *closure_name = Copy(wrapper_name);
if (closure_decl) { if (closure_decl) {
if (!Getattr(n, "sym:overloaded") || !Getattr(n, "sym:nextSibling")) if (!Getattr(n, "sym:overloaded") || !Getattr(n, "sym:nextSibling"))
Printv(f_wrappers, closure_decl, "\n\n", NIL); Printv(f_wrappers, closure_decl, "\n\n", NIL);
Append(closure_name, "_closure"); Append(closure_name, "_closure");
Delete(closure_decl);
} }
Setattr(parent, feature_name, closure_name); Setattr(parent, feature_name, closure_name);
Delete(feature_name); Delete(feature_name);
@ -2611,8 +2673,6 @@ public:
Delete(wname); Delete(wname);
DelWrapper(f); DelWrapper(f);
Delete(wrapper_name); Delete(wrapper_name);
if (closure_decl)
Delete(closure_decl);
return SWIG_OK; return SWIG_OK;
} }
@ -3100,6 +3160,7 @@ public:
String *mname = SwigType_manglestr(rname); String *mname = SwigType_manglestr(rname);
String *pmname = SwigType_manglestr(pname); String *pmname = SwigType_manglestr(pname);
String *templ = NewStringf("SwigPyBuiltin_%s", mname); String *templ = NewStringf("SwigPyBuiltin_%s", mname);
int funpack = modernargs && fastunpack;
Printf(f_init, tab4 "builtin_pytype->ob_type = metatype;\n"); Printf(f_init, tab4 "builtin_pytype->ob_type = metatype;\n");
Printf(f_init, tab4 "builtin_pytype->tp_new = PyType_GenericNew;\n"); Printf(f_init, tab4 "builtin_pytype->tp_new = PyType_GenericNew;\n");
@ -3147,8 +3208,8 @@ public:
Hash *mgetset = member_iter.item; Hash *mgetset = member_iter.item;
String *getter = Getattr(mgetset, "getter"); String *getter = Getattr(mgetset, "getter");
String *setter = Getattr(mgetset, "setter"); String *setter = Getattr(mgetset, "setter");
const char *getter_closure = getter ? "pyswig_getter_closure" : "0"; const char *getter_closure = getter ? funpack ? "pyswig_funpack_getter_closure" : "pyswig_getter_closure" : "0";
const char *setter_closure = setter ? "pyswig_setter_closure" : "0"; const char *setter_closure = setter ? funpack ? "pyswig_funpack_setter_closure" : "pyswig_setter_closure" : "0";
String *gspair = NewStringf("%s_%s_getset", symname, memname); String *gspair = NewStringf("%s_%s_getset", symname, memname);
Printf(f, "static SwigPyGetSet %s = { %s, %s };\n", gspair, getter ? getter : "0", setter ? setter : "0"); Printf(f, "static SwigPyGetSet %s = { %s, %s };\n", gspair, getter ? getter : "0", setter ? setter : "0");
String *entry = String *entry =
@ -3174,13 +3235,15 @@ public:
Printf(f, "%s_richcompare (PyObject *self, PyObject *other, int op)\n", templ); Printf(f, "%s_richcompare (PyObject *self, PyObject *other, int op)\n", templ);
Printf(f, "{\n"); Printf(f, "{\n");
Printf(f, " PyObject *result = NULL;\n"); Printf(f, " PyObject *result = NULL;\n");
Printf(f, " PyObject *tuple = PyTuple_New(1);\n"); if (!funpack) {
Printf(f, " assert(tuple);\n"); Printf(f, " PyObject *tuple = PyTuple_New(1);\n");
Printf(f, " PyTuple_SET_ITEM(tuple, 0, other);\n"); Printf(f, " assert(tuple);\n");
Printf(f, " Py_XINCREF(other);\n"); Printf(f, " PyTuple_SET_ITEM(tuple, 0, other);\n");
Printf(f, " Py_XINCREF(other);\n");
}
Printf(f, " switch (op) {\n"); Printf(f, " switch (op) {\n");
for (Iterator i = First(richcompare); i.item; i = Next(i)) for (Iterator i = First(richcompare); i.item; i = Next(i))
Printf(f, " case %s : result = %s(self, tuple); break;\n", i.key, i.item); Printf(f, " case %s : result = %s(self, %s); break;\n", i.key, i.item, funpack ? "other" : "tuple");
Printv(f, " default : break;\n", NIL); Printv(f, " default : break;\n", NIL);
Printf(f, " }\n"); Printf(f, " }\n");
Printv(f, " if (result == NULL) {\n", NIL); Printv(f, " if (result == NULL) {\n", NIL);
@ -3191,7 +3254,8 @@ public:
Printv(f, " Py_INCREF(result);\n", NIL); Printv(f, " Py_INCREF(result);\n", NIL);
Printv(f, " }\n", NIL); Printv(f, " }\n", NIL);
Printv(f, " }\n", NIL); Printv(f, " }\n", NIL);
Printf(f, " Py_DECREF(tuple);\n"); if (!funpack)
Printf(f, " Py_DECREF(tuple);\n");
Printf(f, " return result;\n"); Printf(f, " return result;\n");
Printf(f, "}\n\n"); Printf(f, "}\n\n");
@ -3705,6 +3769,9 @@ public:
String *symname = Getattr(n, "sym:name"); String *symname = Getattr(n, "sym:name");
int oldshadow; int oldshadow;
if (builtin)
Swig_save("builtin_memberfunc", n, "noargs", "onearg", NIL);
/* Create the default member function */ /* Create the default member function */
oldshadow = shadow; /* Disable shadowing when wrapping member functions */ oldshadow = shadow; /* Disable shadowing when wrapping member functions */
if (shadow) if (shadow)
@ -3719,13 +3786,23 @@ public:
String *fullname = Swig_name_member(NULL, class_name, symname); String *fullname = Swig_name_member(NULL, class_name, symname);
String *wname = Swig_name_wrapper(fullname); String *wname = Swig_name_wrapper(fullname);
Setattr(class_members, symname, n); Setattr(class_members, symname, n);
int allow_kwargs = check_kwargs(n); if (check_kwargs(n)) {
Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_VARARGS%s, \"\" },\n", symname, wname, allow_kwargs ? "|METH_KEYWORDS" : ""); Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_VARARGS|METH_KEYWORDS, \"\" },\n", symname, wname);
} else if (GetFlagAttr(n, "noargs")) {
Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_NOARGS, \"\" },\n", symname, wname);
} else if (GetFlagAttr(n, "onearg")) {
Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_O, \"\" },\n", symname, wname);
} else {
Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_VARARGS, \"\" },\n", symname, wname);
}
Delete(fullname); Delete(fullname);
Delete(wname); Delete(wname);
} }
} }
if (builtin)
Swig_restore(n);
if (!Getattr(n, "sym:nextSibling")) { if (!Getattr(n, "sym:nextSibling")) {
if (shadow && !builtin) { if (shadow && !builtin) {
int fproxy = fastproxy; int fproxy = fastproxy;
@ -3782,6 +3859,7 @@ public:
return SWIG_OK; return SWIG_OK;
} }
/* ------------------------------------------------------------ /* ------------------------------------------------------------
* staticmemberfunctionHandler() * staticmemberfunctionHandler()
* ------------------------------------------------------------ */ * ------------------------------------------------------------ */
@ -3803,7 +3881,14 @@ public:
String *fullname = Swig_name_member(NULL, class_name, symname); String *fullname = Swig_name_member(NULL, class_name, symname);
String *wname = Swig_name_wrapper(fullname); String *wname = Swig_name_wrapper(fullname);
Setattr(class_members, symname, n); Setattr(class_members, symname, n);
String *pyflags = NewString("METH_VARARGS|METH_STATIC"); int funpack = modernargs && fastunpack && !Getattr(n, "sym:overloaded");
String *pyflags = NewString("METH_STATIC|");
if (funpack && GetFlagAttr(n, "noargs"))
Append(pyflags, "METH_NOARGS");
else if (funpack && GetFlagAttr(n, "onearg"))
Append(pyflags, "METH_O");
else
Append(pyflags, "METH_VARARGS");
Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, %s, \"\" },\n", symname, wname, pyflags); Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, %s, \"\" },\n", symname, wname, pyflags);
Delete(fullname); Delete(fullname);
Delete(wname); Delete(wname);
@ -4132,16 +4217,19 @@ public:
DelWrapper(f); DelWrapper(f);
int assignable = is_assignable(n); int assignable = is_assignable(n);
if (assignable) { if (assignable) {
int funpack = modernargs && fastunpack;
Wrapper *f = NewWrapper(); Wrapper *f = NewWrapper();
Printv(f->def, "SWIGINTERN PyObject *", wrapsetname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {", NIL); Printv(f->def, "SWIGINTERN PyObject *", wrapsetname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {", NIL);
Wrapper_add_local(f, "value", "PyObject *value");
Wrapper_add_local(f, "res", "int res"); Wrapper_add_local(f, "res", "int res");
Append(f->code, "if (!PyArg_ParseTuple(args,(char *)\"O:set\",&value)) return NULL;\n"); if (!funpack) {
Printv(f->code, "res = ", varsetname, "(value);\n", NIL); Wrapper_add_local(f, "value", "PyObject *value");
Append(f->code, "if (!PyArg_ParseTuple(args,(char *)\"O:set\",&value)) return NULL;\n");
}
Printf(f->code, "res = %s(%s);\n", varsetname, funpack ? "args" : "value");
Append(f->code, "return !res ? SWIG_Py_Void() : NULL;\n"); Append(f->code, "return !res ? SWIG_Py_Void() : NULL;\n");
Append(f->code, "}\n"); Append(f->code, "}\n");
Wrapper_print(f, f_wrappers); Wrapper_print(f, f_wrappers);
add_method(setname, wrapsetname, 0); add_method(setname, wrapsetname, 0, 0, funpack, 1, 1);
DelWrapper(f); DelWrapper(f);
} }
if (!modern && !builtin) { if (!modern && !builtin) {