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.
197 lines
4.8 KiB
Text
197 lines
4.8 KiB
Text
/* -----------------------------------------------------------------------------
|
|
* clabels.swg
|
|
*
|
|
* Exception handling code and typemaps for C module.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
%typemap(throws) BASIC_INT_TYPES {
|
|
char error_msg[256];
|
|
sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
|
|
SWIG_CThrowException(0, error_msg);
|
|
}
|
|
|
|
%apply BASIC_INT_TYPES { int, long, short, unsigned int, unsigned long, unsigned short, int &, long &, short &, unsigned int &, unsigned long &, unsigned short & };
|
|
|
|
%typemap(throws) char *, const char * {
|
|
SWIG_CThrowException(0, $1);
|
|
}
|
|
|
|
// this should match only SwigObj objects
|
|
%typemap(throws) SWIGTYPE {
|
|
SwigObj *c_ex;
|
|
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($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
|
|
|
|
SWIGEXPORTC struct SWIG_exc_struct {
|
|
int code;
|
|
char *msg;
|
|
SwigObj *klass;
|
|
int handled;
|
|
} SWIG_exc = { 0, 0, 0, 0 };
|
|
|
|
SWIGEXPORTC jmp_buf SWIG_rt_env;
|
|
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++;
|
|
}
|
|
|
|
SWIGINTERN void SWIG_rt_stack_pop() {
|
|
if (SWIG_rt_stack_ptr == SWIG_rt_stack_base)
|
|
return;
|
|
SWIG_rt_stack_ptr--;
|
|
memcpy(SWIG_rt_env, SWIG_rt_stack_ptr, sizeof(SWIG_rt_env));
|
|
}
|
|
|
|
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) {
|
|
free(SWIG_exc.klass);
|
|
}
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
SWIGEXPORTC void SWIG_rt_try() {
|
|
SWIG_rt_stack_push();
|
|
}
|
|
|
|
SWIGEXPORTC int SWIG_rt_catch(const char *type) {
|
|
int result = 0;
|
|
if (!type || (strcmp("SWIG_AnyException", type) == 0)) {
|
|
result = 1;
|
|
}
|
|
else if (SWIG_exc.klass) {
|
|
result = strcmp(SWIG_exc.klass->symname, type) == 0 || SWIG_exc.klass->derives_from(type);
|
|
}
|
|
if (result) {
|
|
SWIG_rt_stack_pop();
|
|
SWIG_exc.handled = 1;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
SWIGEXPORTC void SWIG_rt_throw(SwigObj *klass, const char *msg) {
|
|
if (SWIG_exc.msg) {
|
|
free(SWIG_exc.msg);
|
|
SWIG_exc.msg = (char *) 0;
|
|
}
|
|
if (msg) {
|
|
SWIG_exc.msg = (char *) malloc(strlen(msg) + 1);
|
|
strcpy(SWIG_exc.msg, msg);
|
|
}
|
|
SWIG_exc.klass = klass;
|
|
SWIG_exc.handled = 0;
|
|
longjmp(SWIG_rt_env, 1);
|
|
}
|
|
|
|
SWIGEXPORTC void SWIG_rt_unhandled() {
|
|
if (SWIG_exc.msg) {
|
|
free(SWIG_exc.msg);
|
|
SWIG_exc.msg = 0;
|
|
}
|
|
SWIG_rt_stack_pop();
|
|
longjmp(SWIG_rt_env, SWIG_exc.code);
|
|
}
|
|
|
|
SWIGEXPORTC void SWIG_rt_endtry() {
|
|
if (SWIG_exc.handled) {
|
|
if (setjmp(SWIG_rt_env) == 0) {
|
|
SWIG_rt_stack_push();
|
|
longjmp(SWIG_cpp_back_env, 1);
|
|
}
|
|
}
|
|
else {
|
|
SWIG_rt_stack_pop(); // pop the SWIG_try context
|
|
}
|
|
}
|
|
|
|
SWIGEXPORTC int SWIG_exit(int code) {
|
|
SWIG_cleanup();
|
|
exit(code);
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
SWIGINTERN void SWIG_terminate() {
|
|
fprintf(stderr, "Unhandled exception: %s\n%s\nExitting...\n",
|
|
typeid(*SWIG_exc.klass).name(),
|
|
SWIG_exc.msg ? SWIG_exc.msg : "");
|
|
SWIG_exit(SWIG_exc.code);
|
|
}
|
|
|
|
#define SWIG_CThrowException(klass, msg) \
|
|
if (setjmp(SWIG_cpp_back_env) == 0) \
|
|
SWIG_rt_throw((SwigObj *) klass, msg);
|
|
%}
|
|
|
|
%insert("proxy_header") %{
|
|
// special value indicating any type of exception like 'catch(...)'
|
|
#define SWIG_AnyException "SWIG_AnyException"
|
|
|
|
#include <setjmp.h>
|
|
|
|
SWIGIMPORT jmp_buf SWIG_rt_env;
|
|
|
|
SWIGIMPORT struct SWIG_exc_struct {
|
|
int code;
|
|
char *msg;
|
|
SwigObj *klass;
|
|
} SWIG_exc;
|
|
|
|
SWIGIMPORT void SWIG_rt_try();
|
|
SWIGIMPORT int SWIG_rt_catch(const char *type);
|
|
SWIGIMPORT void SWIG_rt_throw(SwigObj *klass, const char * msg);
|
|
SWIGIMPORT int SWIG_rt_unhandled();
|
|
SWIGIMPORT void SWIG_rt_endtry();
|
|
SWIGIMPORT int SWIG_exit(int code);
|
|
|
|
#define SWIG_try \
|
|
SWIG_rt_try(); \
|
|
if ((SWIG_exc.code = setjmp(SWIG_rt_env)) == 0)
|
|
#define SWIG_catch(type) else if (SWIG_rt_catch(#type))
|
|
#define SWIG_throw(klass) SWIG_rt_throw((SwigObj *) klass, 0);
|
|
#define SWIG_throw_msg(klass, msg) SWIG_rt_throw((SwigObj *) klass, msg);
|
|
#define SWIG_endtry else SWIG_rt_unhandled(); SWIG_rt_endtry();
|
|
|
|
%}
|
|
|