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/SWIG@7965 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2005-12-10 08:10:42 +00:00
commit 49e6084d66
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 table', and avoid multiple GetAttr calls to retreive the python
methods. methods.
*/ */
#ifndef SWIG_DIRECTOR_NOVTABLE #ifndef SWIG_DIRECTOR_NO_VTABLE
#ifndef SWIG_DIRECTOR_VTABLE #ifndef SWIG_DIRECTOR_VTABLE
#define SWIG_DIRECTOR_VTABLE #define SWIG_DIRECTOR_VTABLE
#endif #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 Undefined Exception Handler provided by swift
*/ */
#ifndef SWIG_DIRECTOR_NOUEH #ifndef SWIG_DIRECTOR_NO_UEH
#ifndef SWIG_DIRECTOR_UEH #ifndef SWIG_DIRECTOR_UEH
#define SWIG_DIRECTOR_UEH #define SWIG_DIRECTOR_UEH
#endif #endif

View file

@ -63,6 +63,7 @@ static int nothreads = 0;
static int classptr = 0; static int classptr = 0;
static int shadowimport = 1; static int shadowimport = 1;
static int safecstrings = 0; static int safecstrings = 0;
static int dirvtable = 1;
/* flags for the make_autodoc function */ /* flags for the make_autodoc function */
enum autodoc_t { 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\ -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\ -safecstrings - Use safer (but slower) C string mapping, generating copies from Python -> C/C++\n\
-nosafecstrings - Avoid extra strings copies when possible (default)\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"; \n";
class PYTHON : public Language { class PYTHON : public Language {
@ -263,6 +266,12 @@ public:
} else if (strcmp(argv[i],"-nosafecstrings") == 0) { } else if (strcmp(argv[i],"-nosafecstrings") == 0) {
safecstrings = 0; safecstrings = 0;
Swig_mark_arg(i); 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) { } else if (strcmp(argv[i],"-modern") == 0) {
apply = 0; apply = 0;
classic = 0; classic = 0;
@ -396,6 +405,10 @@ public:
Printf(f_runtime,"#define SWIG_PYTHON_SAFE_CSTRINGS\n"); Printf(f_runtime,"#define SWIG_PYTHON_SAFE_CSTRINGS\n");
} }
if (!dirvtable) {
Printf(f_runtime,"#define SWIG_DIRECTOR_NO_VTABLE\n");
}
/* Set module name */ /* Set module name */
module = Copy(Getattr(n,"name")); module = Copy(Getattr(n,"name"));
@ -2094,8 +2107,9 @@ public:
} }
Printf(f_directors_h,"\n\n"); Printf(f_directors_h,"\n\n");
Printf(f_directors_h,"/* VTable implementation */\n");
Printf(f_directors_h,"public:\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 *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," PyObject *method = vtable[method_index];\n");
Printf(f_directors_h," if (!method) {\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," Py_DECREF(swig_get_self());\n");
Printf(f_directors_h," };\n"); Printf(f_directors_h," };\n");
Printf(f_directors_h," return method;\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,"private:\n");
Printf(f_directors_h," mutable swig::PyObject_var vtable[%d];\n", director_method_index); 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"); Printf(f_directors_h, "};\n\n");
return Language::classDirectorEnd(n); return Language::classDirectorEnd(n);
@ -2960,8 +2975,10 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
Replaceall(tm, "$input", input); Replaceall(tm, "$input", input);
Delete(input); Delete(input);
Replaceall(tm, "$owner", "0"); 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); Printv(wrap_args, tm, "\n", NIL);
Wrapper_add_localv(w, source, "swig::PyObject_var", source, "= 0", NIL);
Printv(arglist, "(PyObject *)",source, NIL); Printv(arglist, "(PyObject *)",source, NIL);
Putc('O', parse_args); Putc('O', parse_args);
} else { } 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); Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
Delete(nonconst_i); Delete(nonconst_i);
Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number, 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 { } else {
nonconst = Copy(ppname); nonconst = Copy(ppname);
} }
@ -3048,9 +3066,6 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
/* add the method name as a PyString */ /* add the method name as a PyString */
String *pyname = Getattr(n,"sym:name"); 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); 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, "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, " Swig::DirectorException::raise(\"'self' unitialized, maybe you forgot to call %s.__init__.\");\n", classname);
Printf(w->code, "}\n"); Printf(w->code, "}\n");
Wrapper_add_local(w, "method", "PyObject* method = 0"); Printf(w->code,"#if defined(SWIG_DIRECTOR_VTABLE)\n");
Printf(w->code, "method = swig_get_method(swig_method_index, swig_method_name);\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, "if (method == NULL) {\n");
Printf(w->code, " Swig::DirectorMethodException::raise(\"Method '%s.%s' doesn't exist\");\n", classname, pyname); Printf(w->code, " Swig::DirectorMethodException::raise(\"Method '%s.%s' doesn't exist\");\n", classname, pyname);
Printf(w->code, "}\n"); Printf(w->code, "}\n");
Wrapper_add_local(w, "result", "swig::PyObject_var result = 0");
if (Len(parse_args) > 0) { if (Len(parse_args) > 0) {
if (use_parse) { 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 { } 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 { } 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)) if (dirprot_mode() && !is_public(n))
Printf(w->code, "swig_set_inner(\"%s\", false);\n", name); Printf(w->code, "swig_set_inner(\"%s\", false);\n", name);