Drastically simplify and optimize object creation and destruction
Don't populate the typenames array for each and every created object and don't search it when deleting every object, this is O(N) in number of classes and is completely impractical for any big library where N can easily be several thousands. Use destructor function which will correctly destroy the object instead. Also don't store each created objects in the global registry, there doesn't seem to be any point in it. And, in fact, don't bother with the typenames at all, just use another pseudo-virtual function for checking whether a class inherits from a class with the given name. There is unfortunately one problem with the new approach: it doesn't work when the same C++ type is wrapped under different names as this results in multiple specializations of SWIG_derives_from<> for this type. But this is a relatively rare situation (but which does arise in template_default2 unit test, which had to be disabled) and could be fixed in the future by completely resolving the type, including the default template parameters values, and checking if SWIG_derives_from had been already specialized for it. In the meanwhile, this regression is not a big deal compared to the advantages of the new approach.
This commit is contained in:
parent
8ff7941503
commit
818b399c9e
6 changed files with 150 additions and 298 deletions
|
|
@ -21,6 +21,7 @@
|
|||
<ul>
|
||||
<li><a href="#C_functions">Functions</a>
|
||||
<li><a href="#C_variables">Variables</a>
|
||||
<li><a href="#C_enums">Enums</a>
|
||||
</ul>
|
||||
<li><a href="#C_basic_cpp_wrapping">Basic C++ wrapping</a>
|
||||
<ul>
|
||||
|
|
@ -324,6 +325,14 @@ By default, SWIG attempts to build a natural C interface to your C/C++ code.
|
|||
This section briefly covers the essential aspects of this wrapping.
|
||||
</p>
|
||||
|
||||
<H3><a name="C_enums"></a>36.3.3 Enums</H3>
|
||||
|
||||
<p>
|
||||
C enums are simply copied to the generated code and keep the same name as in
|
||||
the original code.
|
||||
</p>
|
||||
|
||||
|
||||
<H3><a name="C_classes"></a>36.4.1 Classes</H3>
|
||||
|
||||
|
||||
|
|
@ -522,8 +531,7 @@ SWIGEXPORTC SwigObj * _wrap_someFunction(SwigObj * carg1, int carg2) {
|
|||
const SomeClass &_result_ref = someFunction(*arg1,arg2);cppresult = (SomeClass*) &_result_ref;
|
||||
}
|
||||
{
|
||||
result = (SwigObj*) SWIG_create_object(SWIG_STR(SomeClass));
|
||||
result->obj = (void*) &cppresult;
|
||||
result = SWIG_create_object(cppresult, SWIG_STR(SomeClass));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -604,8 +612,7 @@ At this point we are ready to call the C++ function with our parameters.</br>
|
|||
Subsequently, the return value is assigned to the dedicated return value variable using the 'out' typemap
|
||||
<div class="targetlang"><pre>
|
||||
{
|
||||
result = (SwigObj*) SWIG_create_object(SWIG_STR(SomeClass));
|
||||
result->obj = (void*) &cppresult;
|
||||
result = SWIG_create_object(cppresult, SWIG_STR(SomeClass));
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ FAILING_CPP_TESTS := \
|
|||
special_variables \
|
||||
template_arg_typename \
|
||||
template_basic \
|
||||
template_default2 \
|
||||
template_explicit \
|
||||
template_ns4 \
|
||||
template_tbase_template \
|
||||
|
|
|
|||
61
Lib/c/c.swg
61
Lib/c/c.swg
|
|
@ -273,19 +273,16 @@ same_action_all_primitive_types_but_void(out, "$result = $1;")
|
|||
}
|
||||
|
||||
%typemap(out) SWIGTYPE *&, SWIGTYPE ** {
|
||||
static SwigObj* _ptr = (SwigObj*) SWIG_create_object(SWIG_STR($1_basetype));
|
||||
static SwigObj* _ptr = (SwigObj*) SWIG_create_object($1, SWIG_STR($1_basetype));
|
||||
$result = &_ptr;
|
||||
(*result)->obj = (void*) $1;
|
||||
}
|
||||
|
||||
%typemap(out) SWIGTYPE {
|
||||
$result = (SwigObj*) SWIG_create_object(SWIG_STR($1_basetype));
|
||||
$result->obj = (void*) &$1;
|
||||
$result = (SwigObj*) SWIG_create_object(&$1, SWIG_STR($1_basetype));
|
||||
}
|
||||
|
||||
%typemap(out) SWIGTYPE *, SWIGTYPE & {
|
||||
$result = (SwigObj*) SWIG_create_object(SWIG_STR($1_basetype));
|
||||
$result->obj = (void*) $1;
|
||||
$result = (SwigObj*) SWIG_create_object($1, SWIG_STR($1_basetype));
|
||||
}
|
||||
|
||||
%typemap(out) SWIGTYPE * [ANY], SWIGTYPE [ANY][ANY] {
|
||||
|
|
@ -294,14 +291,13 @@ same_action_all_primitive_types_but_void(out, "$result = $1;")
|
|||
size_t i = 0;
|
||||
if (_temp) {
|
||||
for ( ; i < $1_dim0; ++i)
|
||||
SWIG_destroy_object(_temp[i]);
|
||||
SWIG_destroy_object< $1_ltype >(_temp[i]);
|
||||
free(_temp);
|
||||
}
|
||||
_temp = (SwigObj**) malloc($1_dim0 * sizeof(SwigObj*));
|
||||
for (i = 0 ; i < $1_dim0; ++i) {
|
||||
if ($1[i]) {
|
||||
_temp[i] = SWIG_create_object(SWIG_STR($1_ltype));
|
||||
_temp[i]->obj = (void*) $1[i];
|
||||
_temp[i] = SWIG_create_object($1[i], SWIG_STR($1_ltype));
|
||||
}
|
||||
else
|
||||
_temp[i] = (SwigObj*) 0;
|
||||
|
|
@ -333,31 +329,48 @@ explicit_same_type_unconsted_all_primitive_types_but_void(cppouttype);
|
|||
|
||||
#ifdef SWIG_CPPMODE
|
||||
|
||||
#ifdef SWIG_C_EXCEPT
|
||||
|
||||
%insert("runtime") %{
|
||||
typedef struct {
|
||||
void *obj;
|
||||
const char **typenames;
|
||||
const char* symname;
|
||||
bool (*derives_from)(const char* type);
|
||||
} SwigObj;
|
||||
|
||||
template <class T> SWIGINTERN void SWIG_destroy_object(SwigObj* object) {
|
||||
if (!object)
|
||||
return;
|
||||
|
||||
delete static_cast<T*>(object->obj);
|
||||
|
||||
free(object);
|
||||
}
|
||||
|
||||
template <class T> struct SWIG_derives_from {
|
||||
static bool check(const char* type) { return false; }
|
||||
};
|
||||
|
||||
template <class T> SWIGINTERN SwigObj* SWIG_create_object(T* obj, const char* symname) {
|
||||
SwigObj* const result = (SwigObj*)malloc(sizeof(SwigObj));
|
||||
if (result) {
|
||||
result->obj = const_cast<void*>(static_cast<const void*>(obj));
|
||||
result->symname = symname;
|
||||
result->derives_from = SWIG_derives_from<T>::check;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
%}
|
||||
|
||||
%insert("proxy_header") %{
|
||||
typedef struct {
|
||||
void *obj;
|
||||
const char **typenames;
|
||||
} SwigObj;
|
||||
typedef struct SwigObjStruct SwigObj;
|
||||
%}
|
||||
|
||||
#ifdef SWIG_C_EXCEPT
|
||||
|
||||
%include "cexcept.swg"
|
||||
|
||||
#else
|
||||
|
||||
%insert("runtime") %{
|
||||
typedef struct {
|
||||
void *obj;
|
||||
} SwigObj;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
@ -367,12 +380,6 @@ SWIGEXPORTC int SWIG_exit(int code) { exit(code); }
|
|||
#endif
|
||||
%}
|
||||
|
||||
%insert("proxy_header") %{
|
||||
typedef struct {
|
||||
void *obj;
|
||||
} SwigObj;
|
||||
%}
|
||||
|
||||
#endif
|
||||
#else
|
||||
|
||||
|
|
|
|||
|
|
@ -19,30 +19,24 @@
|
|||
// this should match only SwigObj objects
|
||||
%typemap(throws) SWIGTYPE {
|
||||
SwigObj *c_ex;
|
||||
c_ex = SWIG_create_object(SWIG_STR($1_basetype));
|
||||
c_ex->obj = (void*) &$1;
|
||||
c_ex = SWIG_create_object(&$1, SWIG_STR($1_basetype));
|
||||
SWIG_CThrowException(c_ex, "C++ $1_type exception thrown");
|
||||
}
|
||||
|
||||
%typemap(throws) SWIGTYPE * {
|
||||
SwigObj *c_ex;
|
||||
c_ex = SWIG_create_object(SWIG_STR($1_basetype));
|
||||
c_ex->obj = (void*) $1;
|
||||
c_ex = SWIG_create_object($1, SWIG_STR($1_basetype));
|
||||
SWIG_CThrowException(c_ex, "C++ $1_type exception thrown");
|
||||
}
|
||||
|
||||
%insert("runtime") %{
|
||||
#include <typeinfo>
|
||||
|
||||
SWIGINTERN void SWIG_terminate();
|
||||
|
||||
#define SWIG_MAX_RT_STACK 256
|
||||
#define SWIG_REGISTRY_INIT 256
|
||||
|
||||
SWIGINTERN SwigObj **SWIG_registry_base = 0;
|
||||
SWIGINTERN SwigObj **SWIG_registry = 0;
|
||||
SWIGINTERN int SWIG_registry_size = SWIG_REGISTRY_INIT;
|
||||
|
||||
SWIGINTERN SwigObj *SWIG_create_object(const char *classname);
|
||||
SWIGINTERN void SWIG_destroy_object(SwigObj *object);
|
||||
SWIGINTERN void SWIG_free_SwigObj(SwigObj *object);
|
||||
|
||||
SWIGEXPORTC struct SWIG_exc_struct {
|
||||
int code;
|
||||
char *msg;
|
||||
|
|
@ -51,12 +45,24 @@ SWIGEXPORTC struct SWIG_exc_struct {
|
|||
} SWIG_exc = { 0, 0, 0, 0 };
|
||||
|
||||
SWIGEXPORTC jmp_buf SWIG_rt_env;
|
||||
SWIGEXPORTC int SWIG_rt_init = 0;
|
||||
SWIGINTERN jmp_buf SWIG_cpp_back_env;
|
||||
SWIGINTERN jmp_buf *SWIG_rt_stack_base = 0;
|
||||
SWIGINTERN jmp_buf *SWIG_rt_stack_ptr = 0;
|
||||
|
||||
SWIGINTERN void SWIG_rt_stack_push() {
|
||||
if (!SWIG_rt_stack_base) {
|
||||
SWIG_rt_stack_base = SWIG_rt_stack_ptr = (jmp_buf *) malloc(sizeof(jmp_buf) * SWIG_MAX_RT_STACK);
|
||||
if ((SWIG_exc.code = setjmp(SWIG_rt_env))) {
|
||||
// deallocate C++ exception
|
||||
if (setjmp(SWIG_rt_env) == 0) {
|
||||
SWIG_rt_stack_push();
|
||||
SWIG_exc.handled = 1;
|
||||
longjmp(SWIG_cpp_back_env, 1);
|
||||
}
|
||||
SWIG_terminate();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check for stack overflow
|
||||
memcpy(SWIG_rt_stack_ptr, SWIG_rt_env, sizeof(SWIG_rt_env));
|
||||
SWIG_rt_stack_ptr++;
|
||||
|
|
@ -69,65 +75,14 @@ SWIGINTERN void SWIG_rt_stack_pop() {
|
|||
memcpy(SWIG_rt_env, SWIG_rt_stack_ptr, sizeof(SWIG_rt_env));
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_add_registry_entry(SwigObj *entry) {
|
||||
if (SWIG_registry_base == 0) {
|
||||
SWIG_registry_base = SWIG_registry = (SwigObj **) malloc(SWIG_registry_size * sizeof(SwigObj *));
|
||||
memset(SWIG_registry_base, 0, SWIG_registry_size * sizeof(SwigObj *));
|
||||
}
|
||||
*SWIG_registry = entry;
|
||||
SWIG_registry++;
|
||||
if ((SWIG_registry - SWIG_registry_base) == SWIG_registry_size) {
|
||||
SWIG_registry = SWIG_registry_base;
|
||||
SWIG_registry_size += SWIG_REGISTRY_INIT;
|
||||
int new_size = SWIG_registry_size * sizeof(SwigObj *);
|
||||
SWIG_registry_base = (SwigObj **) malloc(new_size);
|
||||
memset(SWIG_registry_base, 0, new_size);
|
||||
memcpy(SWIG_registry_base, SWIG_registry, (SWIG_registry_size - SWIG_REGISTRY_INIT) * sizeof(SwigObj *));
|
||||
free(SWIG_registry);
|
||||
SWIG_registry = SWIG_registry_base + (SWIG_registry_size - SWIG_REGISTRY_INIT);
|
||||
}
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_remove_registry_entry(SwigObj *entry) {
|
||||
int i;
|
||||
for (i = 0; i < SWIG_registry_size; ++i) {
|
||||
if (*(SWIG_registry_base + i) == entry) {
|
||||
*(SWIG_registry_base + i) = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_free_SwigObj(SwigObj *object) {
|
||||
if (object) {
|
||||
if (object->typenames)
|
||||
free(object->typenames);
|
||||
free(object);
|
||||
object = (SwigObj *) 0;
|
||||
}
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_cleanup() {
|
||||
if (SWIG_rt_stack_base)
|
||||
free(SWIG_rt_stack_base);
|
||||
if (SWIG_exc.msg)
|
||||
free(SWIG_exc.msg);
|
||||
if (SWIG_exc.klass) {
|
||||
if (SWIG_exc.klass->typenames)
|
||||
free(SWIG_exc.klass->typenames);
|
||||
free(SWIG_exc.klass);
|
||||
}
|
||||
int i;
|
||||
if (SWIG_registry_base) {
|
||||
for (i = 0; i < SWIG_registry_size; ++i) {
|
||||
if (*(SWIG_registry_base + i)) {
|
||||
SWIG_free_SwigObj(*(SWIG_registry_base + i));
|
||||
*(SWIG_registry_base + i) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(SWIG_registry_base);
|
||||
SWIG_registry_base = 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -144,13 +99,7 @@ SWIGEXPORTC int SWIG_rt_catch(const char *type) {
|
|||
result = 1;
|
||||
}
|
||||
else if (SWIG_exc.klass) {
|
||||
int i = 0;
|
||||
while (SWIG_exc.klass->typenames[i]) {
|
||||
if (strcmp(SWIG_exc.klass->typenames[i++], type) == 0) {
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = strcmp(SWIG_exc.klass->symname, type) == 0 || SWIG_exc.klass->derives_from(type);
|
||||
}
|
||||
if (result) {
|
||||
SWIG_rt_stack_pop();
|
||||
|
|
@ -205,28 +154,11 @@ SWIGEXPORTC int SWIG_exit(int code) {
|
|||
|
||||
SWIGINTERN void SWIG_terminate() {
|
||||
fprintf(stderr, "Unhandled exception: %s\n%s\nExitting...\n",
|
||||
SWIG_exc.klass->typenames[0],
|
||||
typeid(*SWIG_exc.klass).name(),
|
||||
SWIG_exc.msg ? SWIG_exc.msg : "");
|
||||
SWIG_exit(SWIG_exc.code);
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_runtime_init() {
|
||||
int i, code;
|
||||
if (!SWIG_rt_init) {
|
||||
SWIG_rt_init = 1;
|
||||
SWIG_rt_stack_base = SWIG_rt_stack_ptr = (jmp_buf *) malloc(sizeof(jmp_buf) * SWIG_MAX_RT_STACK);
|
||||
if ((SWIG_exc.code = setjmp(SWIG_rt_env))) {
|
||||
// deallocate C++ exception
|
||||
if (setjmp(SWIG_rt_env) == 0) {
|
||||
SWIG_rt_stack_push();
|
||||
SWIG_exc.handled = 1;
|
||||
longjmp(SWIG_cpp_back_env, 1);
|
||||
}
|
||||
SWIG_terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SWIG_CThrowException(klass, msg) \
|
||||
if (setjmp(SWIG_cpp_back_env) == 0) \
|
||||
SWIG_rt_throw((SwigObj *) klass, msg);
|
||||
|
|
|
|||
|
|
@ -216,8 +216,7 @@ struct SWIG_CException {
|
|||
%}
|
||||
|
||||
#define SWIG_exception(code, msg)\
|
||||
SwigObj *_ex = SWIG_create_object("SWIG_CException"); \
|
||||
_ex->obj = (void *) new SWIG_CException(code); \
|
||||
SwigObj *_ex = SWIG_create_object(new SWIG_CException(code), "SWIG_CException"); \
|
||||
SWIG_CThrowException(_ex, msg);
|
||||
|
||||
#endif // SWIGC
|
||||
|
|
|
|||
|
|
@ -101,14 +101,13 @@ class C:public Language {
|
|||
File *f_runtime;
|
||||
File *f_header;
|
||||
File *f_wrappers;
|
||||
File *f_wrappers_cxx;
|
||||
File *f_wrappers_types;
|
||||
File *f_wrappers_decl;
|
||||
File *f_init;
|
||||
|
||||
String *empty_string;
|
||||
String *int_string;
|
||||
String *create_object;
|
||||
String *destroy_object;
|
||||
String *tl_namespace; // optional top level namespace
|
||||
|
||||
bool except_flag;
|
||||
|
|
@ -122,8 +121,6 @@ public:
|
|||
C() :
|
||||
empty_string(NewString("")),
|
||||
int_string(NewString("int")),
|
||||
create_object(0),
|
||||
destroy_object(0),
|
||||
tl_namespace(NULL),
|
||||
except_flag(true) {
|
||||
}
|
||||
|
|
@ -323,54 +320,6 @@ public:
|
|||
allow_overloading();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* start_create_object()
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
void start_create_object() {
|
||||
String *s = create_object = NewString("");
|
||||
Printv(s, "\nSWIGINTERN SwigObj *SWIG_create_object(", except_flag ? "const char *classname" : "", ") {\n", NIL);
|
||||
if (except_flag)
|
||||
Printf(s, "SWIG_runtime_init();\n");
|
||||
Printf(s, "SwigObj *result;\n");
|
||||
Printf(s, "result = (SwigObj *) malloc(sizeof(SwigObj));\n");
|
||||
Printf(s, "result->obj = 0;\n");
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* finish_create_object()
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
String *finish_create_object() {
|
||||
String *s = create_object;
|
||||
Printf(s, "SWIG_add_registry_entry(result);\n");
|
||||
Printf(s, "return result;\n");
|
||||
Printf(s, "}\n\n");
|
||||
return create_object;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* start_destroy_object()
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
void start_destroy_object() {
|
||||
String *s = destroy_object = NewString("");
|
||||
Printf(s, "\nSWIGINTERN void SWIG_destroy_object(SwigObj *object) {\n");
|
||||
Printf(s, "if (object) {\n");
|
||||
if (except_flag)
|
||||
Printf(s, "if (object->typenames) {\n");
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* finish_destroy_object()
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
String *finish_destroy_object() {
|
||||
String *s = destroy_object;
|
||||
Printf(s, "SWIG_free_SwigObj(object);\n}\n}\n}\n");
|
||||
return destroy_object;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* top()
|
||||
* --------------------------------------------------------------------- */
|
||||
|
|
@ -389,6 +338,7 @@ public:
|
|||
f_init = NewString("");
|
||||
f_header = NewString("");
|
||||
f_wrappers = NewString("");
|
||||
f_wrappers_cxx = NewString("");
|
||||
|
||||
Swig_banner(f_begin);
|
||||
|
||||
|
|
@ -438,19 +388,9 @@ public:
|
|||
cplusplus_guard_wrappers(f_wrappers),
|
||||
cplusplus_guard_wrappers_h(f_wrappers_h_body);
|
||||
|
||||
if (except_flag) {
|
||||
start_create_object();
|
||||
start_destroy_object();
|
||||
}
|
||||
|
||||
// emit code for children
|
||||
Language::top(n);
|
||||
|
||||
if (except_flag) {
|
||||
Append(f_header, finish_create_object());
|
||||
Append(f_header, finish_destroy_object());
|
||||
}
|
||||
|
||||
Dump(f_wrappers_types, f_wrappers_h_body);
|
||||
Delete(f_wrappers_types);
|
||||
|
||||
|
|
@ -464,6 +404,7 @@ public:
|
|||
|
||||
// write all to the file
|
||||
Dump(f_header, f_runtime);
|
||||
Dump(f_wrappers_cxx, f_runtime);
|
||||
Wrapper_pretty_print(f_wrappers, f_runtime);
|
||||
Dump(f_init, f_runtime);
|
||||
Dump(f_runtime, f_begin);
|
||||
|
|
@ -472,6 +413,7 @@ public:
|
|||
Delete(f_begin);
|
||||
Delete(f_header);
|
||||
Delete(f_wrappers);
|
||||
Delete(f_wrappers_cxx);
|
||||
Delete(f_wrappers_h);
|
||||
Delete(f_init);
|
||||
Delete(f_runtime);
|
||||
|
|
@ -1343,46 +1285,73 @@ ready:
|
|||
if (CPlusPlus) {
|
||||
// inheritance support: attach all members from base classes to this class
|
||||
if (baselist) {
|
||||
Iterator i;
|
||||
for (i = First(baselist); i.item; i = Next(i)) {
|
||||
// look for member variables and functions
|
||||
Node *node;
|
||||
for (node = firstChild(i.item); node; node = nextSibling(node)) {
|
||||
if ((Cmp(Getattr(node, "kind"), "variable") == 0)
|
||||
|| (Cmp(Getattr(node, "kind"), "function") == 0)) {
|
||||
if ((Cmp(Getattr(node, "access"), "public") == 0)
|
||||
&& (Cmp(Getattr(node, "storage"), "static") != 0)) {
|
||||
Node *new_node = copy_node(node);
|
||||
String *parent_name = Getattr(parentNode(node), "name");
|
||||
Hash *dupl_name_node = is_in(Getattr(node, "name"), n);
|
||||
// if there's a duplicate inherited name, due to the C++ multiple
|
||||
// inheritance, change both names to avoid ambiguity
|
||||
if (dupl_name_node) {
|
||||
String *cif = Getattr(dupl_name_node, "c:inherited_from");
|
||||
String *old_name = Getattr(dupl_name_node, "name");
|
||||
if (cif && parent_name && (Cmp(cif, parent_name) != 0)) {
|
||||
Setattr(dupl_name_node, "name", NewStringf("%s%s", cif ? cif : "", old_name));
|
||||
Setattr(dupl_name_node, "c:base_name", old_name);
|
||||
Setattr(new_node, "name", NewStringf("%s%s", parent_name, old_name));
|
||||
Setattr(new_node, "c:base_name", old_name);
|
||||
Setattr(new_node, "c:inherited_from", parent_name);
|
||||
Setattr(new_node, "sym:name", Getattr(new_node, "name"));
|
||||
Setattr(new_node, "sym:symtab", Getattr(n, "symtab"));
|
||||
set_nodeType(new_node, "cdecl");
|
||||
appendChild(n, new_node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Setattr(new_node, "c:inherited_from", parent_name);
|
||||
Setattr(new_node, "sym:name", Getattr(new_node, "name"));
|
||||
Setattr(new_node, "sym:symtab", Getattr(n, "symtab"));
|
||||
set_nodeType(new_node, "cdecl");
|
||||
appendChild(n, new_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// We may need to specialize SWIG_derives_from<> for this class: its unique check() method will return true iff it's given the name of any subclasses of
|
||||
// this class. Notice that it may happen that all our base classes are ignored, in which case we don't do anything.
|
||||
bool started_derives_from_spec = false;
|
||||
|
||||
Iterator i;
|
||||
for (i = First(baselist); i.item; i = Next(i)) {
|
||||
// look for member variables and functions
|
||||
Node *node;
|
||||
for (node = firstChild(i.item); node; node = nextSibling(node)) {
|
||||
if ((Cmp(Getattr(node, "kind"), "variable") == 0)
|
||||
|| (Cmp(Getattr(node, "kind"), "function") == 0)) {
|
||||
if ((Cmp(Getattr(node, "access"), "public") == 0)
|
||||
&& (Cmp(Getattr(node, "storage"), "static") != 0)) {
|
||||
Node *new_node = copy_node(node);
|
||||
String *parent_name = Getattr(parentNode(node), "name");
|
||||
Hash *dupl_name_node = is_in(Getattr(node, "name"), n);
|
||||
// if there's a duplicate inherited name, due to the C++ multiple
|
||||
// inheritance, change both names to avoid ambiguity
|
||||
if (dupl_name_node) {
|
||||
String *cif = Getattr(dupl_name_node, "c:inherited_from");
|
||||
String *old_name = Getattr(dupl_name_node, "name");
|
||||
if (cif && parent_name && (Cmp(cif, parent_name) != 0)) {
|
||||
Setattr(dupl_name_node, "name", NewStringf("%s%s", cif ? cif : "", old_name));
|
||||
Setattr(dupl_name_node, "c:base_name", old_name);
|
||||
Setattr(new_node, "name", NewStringf("%s%s", parent_name, old_name));
|
||||
Setattr(new_node, "c:base_name", old_name);
|
||||
Setattr(new_node, "c:inherited_from", parent_name);
|
||||
Setattr(new_node, "sym:name", Getattr(new_node, "name"));
|
||||
Setattr(new_node, "sym:symtab", Getattr(n, "symtab"));
|
||||
set_nodeType(new_node, "cdecl");
|
||||
appendChild(n, new_node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Setattr(new_node, "c:inherited_from", parent_name);
|
||||
Setattr(new_node, "sym:name", Getattr(new_node, "name"));
|
||||
Setattr(new_node, "sym:symtab", Getattr(n, "symtab"));
|
||||
set_nodeType(new_node, "cdecl");
|
||||
appendChild(n, new_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Account for this base class in the RTTI checks.
|
||||
String* const name = Getattr(i.item, "sym:name");
|
||||
if (name) {
|
||||
if (!started_derives_from_spec) {
|
||||
started_derives_from_spec = true;
|
||||
|
||||
Printv(f_wrappers_cxx,
|
||||
"template<> struct SWIG_derives_from< ", Getattr(n, "classtype"), " > {\n",
|
||||
" static bool check(const char* type) {\n",
|
||||
" return ",
|
||||
NIL);
|
||||
} else {
|
||||
Printv(f_wrappers_cxx, " ||\n ", NIL);
|
||||
}
|
||||
|
||||
Printv(f_wrappers_cxx, "strcmp(type, \"", name, "\") == 0", NIL);
|
||||
}
|
||||
}
|
||||
|
||||
if (started_derives_from_spec) {
|
||||
// End SWIG_derives_from specialization.
|
||||
Printv(f_wrappers_cxx, ";\n }\n};\n\n", NIL);
|
||||
}
|
||||
}
|
||||
|
||||
// declare type for specific class in the proxy header
|
||||
|
|
@ -1499,46 +1468,6 @@ ready:
|
|||
return Language::membervariableHandler(n);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* add_to_create_object()
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
void add_to_create_object(Node *n, String *classname, String *newclassname) {
|
||||
String *s = create_object;
|
||||
|
||||
Printv(s, "if (strcmp(classname, \"", classname, "\") == 0) {\n", NIL);
|
||||
|
||||
// store the name of each class in the hierarchy
|
||||
List *baselist = Getattr(Swig_methodclass(n), "bases");
|
||||
Printf(s, "result->typenames = (const char **) malloc(%d*sizeof(const char*));\n", Len(baselist) + 2);
|
||||
Printv(s, "result->typenames[0] = Swig_typename_", newclassname, ";\n", NIL);
|
||||
int i = 1;
|
||||
if (baselist) {
|
||||
Iterator it;
|
||||
for (it = First(baselist); it.item; it = Next(it)) {
|
||||
String *kname = Getattr(it.item, "sym:name");
|
||||
if (kname)
|
||||
Printf(s, "result->typenames[%d] = Swig_typename_%s;\n", i++, kname);
|
||||
}
|
||||
}
|
||||
Printf(s, "result->typenames[%d] = 0;\n", i);
|
||||
Printf(s, "}\n");
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* add_to_destroy_object()
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
void add_to_destroy_object(Node *n, String *classname, String *classtype) {
|
||||
String *s = destroy_object;
|
||||
String *access = Getattr(n, "access");
|
||||
if (access && Cmp(access, "private") != 0) {
|
||||
Printv(s, "if (strcmp(object->typenames[0], \"", classname, "\") == 0) {\n", NIL);
|
||||
Printv(s, "if (object->obj)\ndelete (", classtype, " *) (object->obj);\n", NIL);
|
||||
Printf(s, "}\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* constructorHandler()
|
||||
* --------------------------------------------------------------------- */
|
||||
|
|
@ -1551,7 +1480,6 @@ ready:
|
|||
return copyconstructorHandler(n);
|
||||
|
||||
Node *klass = Swig_methodclass(n);
|
||||
String *classname = Getattr(klass, "name");
|
||||
String *newclassname = Getattr(klass, "sym:name");
|
||||
String *sobj_name = NewString("");
|
||||
String *ctype;
|
||||
|
|
@ -1582,17 +1510,12 @@ ready:
|
|||
Setattr(n, "sym:name", constr_name);
|
||||
|
||||
// generate action code
|
||||
if (except_flag) {
|
||||
if (!Getattr(klass, "c:create")) {
|
||||
add_to_create_object(n, classname, newclassname);
|
||||
Setattr(klass, "c:create", "1");
|
||||
}
|
||||
Printv(code, "result = SWIG_create_object(\"", classname, "\");\n", NIL);
|
||||
if (!Getattr(klass, "c:create")) {
|
||||
Setattr(klass, "c:create", "1");
|
||||
}
|
||||
else {
|
||||
Printf(code, "result = SWIG_create_object();\n");
|
||||
}
|
||||
Printv(code, "result->obj = (void*) new ", Getattr(klass, "classtype"), arg_lnames, ";\n", NIL);
|
||||
Printv(code, "result = SWIG_create_object(new ", Getattr(klass, "classtype"), arg_lnames,
|
||||
", \"", newclassname, "\");\n",
|
||||
NIL);
|
||||
|
||||
Setattr(n, "wrap:action", code);
|
||||
functionWrapper(n);
|
||||
|
|
@ -1641,17 +1564,12 @@ ready:
|
|||
Setattr(n, "sym:name", constr_name);
|
||||
|
||||
// generate action code
|
||||
if (except_flag) {
|
||||
if (!Getattr(klass, "c:create")) {
|
||||
add_to_create_object(n, classname, newclassname);
|
||||
Setattr(klass, "c:create", "1");
|
||||
}
|
||||
Printv(code, "result = SWIG_create_object(\"", classname, "\");\n", NIL);
|
||||
if (!Getattr(klass, "c:create")) {
|
||||
Setattr(klass, "c:create", "1");
|
||||
}
|
||||
else {
|
||||
Printf(code, "result = SWIG_create_object();\n");
|
||||
}
|
||||
Printv(code, "result->obj = (void*) new ", classname, "((", classname, " const &)*arg1);\n", NIL);
|
||||
Printv(code, "result = SWIG_create_object(new ", classname, "((", classname, " const &)*arg1)",
|
||||
", \"", newclassname, "\");\n",
|
||||
NIL);
|
||||
|
||||
Setattr(n, "wrap:action", code);
|
||||
functionWrapper(n);
|
||||
|
|
@ -1673,8 +1591,6 @@ ready:
|
|||
return SWIG_NOWRAP;
|
||||
|
||||
Node *klass = Swig_methodclass(n);
|
||||
String *classname = Getattr(klass, "name");// Remove class namespace from constructor
|
||||
String *classtype = Getattr(klass, "classtype");
|
||||
String *newclassname = Getattr(klass, "sym:name");
|
||||
String *sobj_name = NewString("");
|
||||
String *ctype;
|
||||
|
|
@ -1704,15 +1620,7 @@ ready:
|
|||
Setattr(n, "sym:name", destr_name);
|
||||
|
||||
// create action code
|
||||
if (except_flag) {
|
||||
add_to_destroy_object(n, classname, classtype);
|
||||
Printf(code, "SWIG_remove_registry_entry(carg1);\n");
|
||||
Printf(code, "SWIG_destroy_object(carg1);");
|
||||
}
|
||||
else {
|
||||
Printv(code, "if (carg1->obj)\ndelete (", classtype, " *) (carg1->obj);\n", NIL);
|
||||
}
|
||||
|
||||
Printv(code, "SWIG_destroy_object< ", Getattr(klass, "classtype"), " >(carg1);", NIL);
|
||||
Setattr(n, "wrap:action", code);
|
||||
|
||||
functionWrapper(n);
|
||||
|
|
@ -1776,8 +1684,6 @@ ready:
|
|||
}
|
||||
Append(name, Swig_name_mangle(Getattr(n, "sym:name")));
|
||||
Setattr(n, "sym:name", name);
|
||||
if (except_flag)
|
||||
Printv(f_header, "const char* Swig_typename_", name, " = \"", Getattr(n, "name"), "\";\n\n", NIL);
|
||||
return Language::classDeclaration(n);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue