add the dirvtable/nodirvtable options to enable/disable the new pseudo virtual table for directors

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@7965 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2005-12-10 08:10:42 +00:00
commit fa93e11666
2 changed files with 43 additions and 18 deletions

View file

@ -19,12 +19,12 @@
/*
Use -DSWIG_DIRECTOR_NOVTABLE if you don't want to generate a 'virtual
Use -DSWIG_DIRECTOR_NO_VTABLE if you don't want to generate a 'virtual
table', and avoid multiple GetAttr calls to retreive the python
methods.
*/
#ifndef SWIG_DIRECTOR_NOVTABLE
#ifndef SWIG_DIRECTOR_NO_VTABLE
#ifndef SWIG_DIRECTOR_VTABLE
#define SWIG_DIRECTOR_VTABLE
#endif
@ -33,10 +33,10 @@
/*
Use -DSWIG_DIRECTOR_NOUEH if you prefer to avoid the use of the
Use -DSWIG_DIRECTOR_NO_UEH if you prefer to avoid the use of the
Undefined Exception Handler provided by swift
*/
#ifndef SWIG_DIRECTOR_NOUEH
#ifndef SWIG_DIRECTOR_NO_UEH
#ifndef SWIG_DIRECTOR_UEH
#define SWIG_DIRECTOR_UEH
#endif

View file

@ -63,6 +63,7 @@ static int nothreads = 0;
static int classptr = 0;
static int shadowimport = 1;
static int safecstrings = 0;
static int dirvtable = 1;
/* flags for the make_autodoc function */
enum autodoc_t {
@ -98,6 +99,8 @@ Python Options (available with -python)\n\
-noproxyimport - Don't insert proxy import statements derived from the %import directive \n\
-safecstrings - Use safer (but slower) C string mapping, generating copies from Python -> C/C++\n\
-nosafecstrings - Avoid extra strings copies when possible (default)\n\
-dirvtable - Generate a pseudo virtual table for directors for faster dispatch (default) \n\
-nodirvtable - Don't use the virtual table feature, resolve the python method each time\n\
\n";
class PYTHON : public Language {
@ -263,6 +266,12 @@ public:
} else if (strcmp(argv[i],"-nosafecstrings") == 0) {
safecstrings = 0;
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-dirvtable") == 0) {
dirvtable = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-nodirvtable") == 0) {
dirvtable = 0;
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-modern") == 0) {
apply = 0;
classic = 0;
@ -395,6 +404,10 @@ public:
if (safecstrings) {
Printf(f_runtime,"#define SWIG_PYTHON_SAFE_CSTRINGS\n");
}
if (!dirvtable) {
Printf(f_runtime,"#define SWIG_DIRECTOR_NO_VTABLE\n");
}
/* Set module name */
@ -2094,8 +2107,9 @@ public:
}
Printf(f_directors_h,"\n\n");
Printf(f_directors_h,"/* VTable implementation */\n");
Printf(f_directors_h,"public:\n");
Printf(f_directors_h,"#if defined(SWIG_DIRECTOR_VTABLE)\n");
Printf(f_directors_h,"/* VTable implementation */\n");
Printf(f_directors_h," PyObject *swig_get_method(size_t method_index, const char *method_name) const {\n");
Printf(f_directors_h," PyObject *method = vtable[method_index];\n");
Printf(f_directors_h," if (!method) {\n");
@ -2104,9 +2118,10 @@ public:
Printf(f_directors_h," Py_DECREF(swig_get_self());\n");
Printf(f_directors_h," };\n");
Printf(f_directors_h," return method;\n");
Printf(f_directors_h," }\n\n");
Printf(f_directors_h," }\n");
Printf(f_directors_h,"private:\n");
Printf(f_directors_h," mutable swig::PyObject_var vtable[%d];\n", director_method_index);
Printf(f_directors_h,"#endif\n\n");
Printf(f_directors_h, "};\n\n");
return Language::classDirectorEnd(n);
@ -2960,8 +2975,10 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
Replaceall(tm, "$input", input);
Delete(input);
Replaceall(tm, "$owner", "0");
/* Wrapper_add_localv(w, source, "swig::PyObject_var", source, "= 0", NIL);*/
Printv(wrap_args, "swig::PyObject_var ", source, ";\n", NIL);
Printv(wrap_args, tm, "\n", NIL);
Wrapper_add_localv(w, source, "swig::PyObject_var", source, "= 0", NIL);
Printv(arglist, "(PyObject *)",source, NIL);
Putc('O', parse_args);
} else {
@ -3004,7 +3021,8 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
Delete(nonconst_i);
Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
"Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(ptype, pname), classname, name);
"Target language argument '%s' discards const in director method %s::%s.\n",
SwigType_str(ptype, pname), classname, name);
} else {
nonconst = Copy(ppname);
}
@ -3048,9 +3066,6 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
/* add the method name as a PyString */
String *pyname = Getattr(n,"sym:name");
Wrapper_add_localv(w, "swig_method_index", "const size_t swig_method_index =", NewStringf("%d", director_method_index++), NIL);
Wrapper_add_localv(w, "swig_method_name", "const char * const swig_method_name =", NewStringf("\"%s\"",pyname), NIL);
int allow_thread = threads_enable(n);
@ -3097,22 +3112,32 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
Printf(w->code, "if (!swig_get_self()) {\n");
Printf(w->code, " Swig::DirectorException::raise(\"'self' unitialized, maybe you forgot to call %s.__init__.\");\n", classname);
Printf(w->code, "}\n");
Wrapper_add_local(w, "method", "PyObject* method = 0");
Printf(w->code, "method = swig_get_method(swig_method_index, swig_method_name);\n");
Printf(w->code,"#if defined(SWIG_DIRECTOR_VTABLE)\n");
Printf(w->code, "const size_t swig_method_index = %d;\n", director_method_index++);
Printf(w->code, "const char * const swig_method_name = \"%s\";\n", pyname);
Printf(w->code, "PyObject* method = swig_get_method(swig_method_index, swig_method_name);\n");
Printf(w->code, "if (method == NULL) {\n");
Printf(w->code, " Swig::DirectorMethodException::raise(\"Method '%s.%s' doesn't exist\");\n", classname, pyname);
Printf(w->code, "}\n");
Wrapper_add_local(w, "result", "swig::PyObject_var result = 0");
if (Len(parse_args) > 0) {
if (use_parse) {
Printf(w->code, "result = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", parse_args, arglist);
Printf(w->code, "swig::PyObject_var result = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", parse_args, arglist);
} else {
Printf(w->code, "result = PyObject_CallFunctionObjArgs(method %s, NULL);\n", arglist);
Printf(w->code, "swig::PyObject_var result = PyObject_CallFunctionObjArgs(method %s, NULL);\n", arglist);
}
} else {
Printf(w->code, "result = PyObject_CallFunction(method, NULL);\n");
Printf(w->code, "static swig::PyObject_var args = PyTuple_New(0);\n");
Printf(w->code, "swig::PyObject_var result = PyObject_Call(method, (PyObject*) args, NULL);\n");
}
Printf(w->code,"#else\n");
if (Len(parse_args) > 0) {
Printf(w->code, "swig::PyObject_var result = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", (char *)\"(%s)\" %s);\n", pyname, parse_args, arglist);
} else {
Printf(w->code, "swig::PyObject_var result = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", NULL);\n", pyname);
}
Printf(w->code,"#endif\n");
if (dirprot_mode() && !is_public(n))
Printf(w->code, "swig_set_inner(\"%s\", false);\n", name);