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:
Vadim Zeitlin 2016-04-14 01:41:08 +02:00
commit 818b399c9e
6 changed files with 150 additions and 298 deletions

View file

@ -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>

View file

@ -95,6 +95,7 @@ FAILING_CPP_TESTS := \
special_variables \
template_arg_typename \
template_basic \
template_default2 \
template_explicit \
template_ns4 \
template_tbase_template \

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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);
}