Fixed a bug in the Ruby director code for the handling of deeply nested
exceptions; now they should just be re-raised until they percolate to the top. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4848 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
7740019f91
commit
da5a15c730
1 changed files with 19 additions and 5 deletions
|
|
@ -2123,14 +2123,15 @@ public:
|
||||||
*
|
*
|
||||||
* --------------------------------------------------------------- */
|
* --------------------------------------------------------------- */
|
||||||
|
|
||||||
void exceptionSafeMethodCall(Node *n, Wrapper *w, int argc, String *args) {
|
void exceptionSafeMethodCall(String *className, Node *n, Wrapper *w, int argc, String *args) {
|
||||||
|
|
||||||
Wrapper *body = NewWrapper();
|
Wrapper *body = NewWrapper();
|
||||||
Wrapper *rescue = NewWrapper();
|
Wrapper *rescue = NewWrapper();
|
||||||
|
|
||||||
String *methodName = Getattr(n, "sym:name");
|
String *methodName = Getattr(n, "sym:name");
|
||||||
String *bodyName = NewStringf("%s_body", methodName);
|
String *bodyName = NewStringf("%s_%s_body", className, methodName);
|
||||||
String *rescueName = NewStringf("%s_rescue", methodName);
|
String *rescueName = NewStringf("%s_%s_rescue", className, methodName);
|
||||||
|
String *depthCountName = NewStringf("%s_%s_call_depth", className, methodName);
|
||||||
|
|
||||||
// Check for an exception typemap of some kind
|
// Check for an exception typemap of some kind
|
||||||
String *tm = Swig_typemap_lookup_new("director:except", n, "result", 0);
|
String *tm = Swig_typemap_lookup_new("director:except", n, "result", 0);
|
||||||
|
|
@ -2140,16 +2141,28 @@ public:
|
||||||
|
|
||||||
if ((tm != 0) && (Len(tm) > 0) && (Strcmp(tm, "1") != 0))
|
if ((tm != 0) && (Len(tm) > 0) && (Strcmp(tm, "1") != 0))
|
||||||
{
|
{
|
||||||
|
// Declare a global to hold the depth count
|
||||||
|
Printf(f_directors, "static int %s = 0;\n", depthCountName);
|
||||||
|
|
||||||
// Function body
|
// Function body
|
||||||
Printf(body->def, "VALUE %s(VALUE data) {\n", bodyName);
|
Printf(body->def, "VALUE %s(VALUE data) {\n", bodyName);
|
||||||
Wrapper_add_localv(body, "args", "swig_body_args *", "args", "= reinterpret_cast<swig_body_args *>(data)", NIL);
|
Wrapper_add_localv(body, "args", "swig_body_args *", "args", "= reinterpret_cast<swig_body_args *>(data)", NIL);
|
||||||
Printv(body->code, "return rb_funcall2(args->recv, args->id, args->argc, args->argv);\n", NIL);
|
Wrapper_add_localv(body, "result", "VALUE", "result", "= Qnil", NIL);
|
||||||
|
Printf(body->code, "%s++;\n", depthCountName, NIL);
|
||||||
|
Printv(body->code, "result = rb_funcall2(args->recv, args->id, args->argc, args->argv);\n", NIL);
|
||||||
|
Printf(body->code, "%s--;\n", depthCountName, NIL);
|
||||||
|
Printv(body->code, "return result;\n", NIL);
|
||||||
Printv(body->code, "}", NIL);
|
Printv(body->code, "}", NIL);
|
||||||
|
|
||||||
// Exception handler
|
// Exception handler
|
||||||
Printf(rescue->def, "VALUE %s(VALUE args, VALUE error) {\n", rescueName);
|
Printf(rescue->def, "VALUE %s(VALUE args, VALUE error) {\n", rescueName);
|
||||||
Replaceall(tm, "$error", "error");
|
Replaceall(tm, "$error", "error");
|
||||||
|
Printf(rescue->code, "if (%s == 0) ", depthCountName);
|
||||||
Printv(rescue->code, Str(tm), "\n", NIL);
|
Printv(rescue->code, Str(tm), "\n", NIL);
|
||||||
|
Printv(rescue->code, "else {\n", NIL);
|
||||||
|
Printf(rescue->code, "%s--;\n", depthCountName);
|
||||||
|
Printv(rescue->code, "rb_raise(error, \"\");\n", NIL);
|
||||||
|
Printv(rescue->code, "}", NIL);
|
||||||
Printv(rescue->code, "}", NIL);
|
Printv(rescue->code, "}", NIL);
|
||||||
|
|
||||||
// Main code
|
// Main code
|
||||||
|
|
@ -2189,6 +2202,7 @@ public:
|
||||||
// Clean up
|
// Clean up
|
||||||
Delete(bodyName);
|
Delete(bodyName);
|
||||||
Delete(rescueName);
|
Delete(rescueName);
|
||||||
|
Delete(depthCountName);
|
||||||
DelWrapper(body);
|
DelWrapper(body);
|
||||||
DelWrapper(rescue);
|
DelWrapper(rescue);
|
||||||
}
|
}
|
||||||
|
|
@ -2396,7 +2410,7 @@ public:
|
||||||
Printv(w->code, wrap_args, NIL);
|
Printv(w->code, wrap_args, NIL);
|
||||||
|
|
||||||
/* pass the method call on to the Ruby object */
|
/* pass the method call on to the Ruby object */
|
||||||
exceptionSafeMethodCall(n, w, idx, arglist);
|
exceptionSafeMethodCall(classname, n, w, idx, arglist);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ruby method may return a simple object, or an Array of objects.
|
* Ruby method may return a simple object, or an Array of objects.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue