Skip to content

Commit

Permalink
improve director exception propagation
Browse files Browse the repository at this point in the history
  • Loading branch information
mcorino committed Oct 21, 2023
1 parent e3a0038 commit 0e056b4
Showing 1 changed file with 16 additions and 8 deletions.
24 changes: 16 additions & 8 deletions rakelib/lib/core/include/funcall.inc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

typedef VALUE (*RUBY_INVOKE_FUNC) (VALUE);

VALUE rb_exc_set_backtrace(VALUE, VALUE);
VALUE rb_get_backtrace(VALUE);

namespace Swig {
/* Base class for director exceptions */
class DirectorException : public std::exception
Expand Down Expand Up @@ -60,9 +63,13 @@ namespace Swig {
class DirectorRubyException : public DirectorException
{
public:
DirectorRubyException(VALUE error)
: DirectorException(error)
DirectorRubyException(VALUE error, VALUE rcvr, ID fn_id)
: DirectorException(Qnil)
{
VALUE msg = rb_sprintf("Caught exception in SWIG director method for %s#%s", rb_class2name(CLASS_OF(rcvr)), rb_id2name(fn_id));
swig_error = rb_exc_new_str(rb_eRuntimeError, msg);
VALUE bt = rb_funcall(error, rb_intern("backtrace"), 0);
rb_funcall(swig_error, rb_intern("set_backtrace"), 1, bt);
}
};
}
Expand Down Expand Up @@ -99,15 +106,18 @@ public:

bool has_caught_exception () { return this->ex_caught_; }

VALUE get_exception () { return rb_gv_get ("$!"); }
VALUE get_exception () { return rb_errinfo(); }

ID id () { return this->fn_id_; }

protected:
struct FuncArgs
{
FuncArgs(VALUE rcvr) : receiver_(rcvr) {}
virtual ~FuncArgs () {}
virtual VALUE rb_invoke (ID fnid) const = 0;

VALUE receiver_;
};

VALUE _invoke (const FuncArgs& fa)
Expand All @@ -125,7 +135,7 @@ protected:
{
// handle exception
VALUE rexc = this->get_exception ();
throw Swig::DirectorRubyException(rexc);
throw Swig::DirectorRubyException(rexc, fa.receiver_, this->fn_id_);
}
else
{
Expand All @@ -142,30 +152,28 @@ protected:
struct FuncArgArray : public FuncArgs
{
FuncArgArray (VALUE rcvr, VALUE args)
: receiver_ (rcvr), args_ (args) {}
: FuncArgs (rcvr), args_ (args) {}
virtual ~FuncArgArray () {}

virtual VALUE rb_invoke (ID fnid) const
{
return rb_apply (this->receiver_, fnid, this->args_);
}

VALUE receiver_;
VALUE args_;
};

struct FuncArgList : public FuncArgs
{
FuncArgList (VALUE rcvr, int argc, VALUE* args)
: receiver_ (rcvr), argc_ (argc), args_ (args) {}
: FuncArgs (rcvr), argc_ (argc), args_ (args) {}
virtual ~FuncArgList () {}

virtual VALUE rb_invoke (ID fnid) const
{
return rb_funcall2 (this->receiver_, fnid, this->argc_, this->args_);
}

VALUE receiver_;
int argc_;
VALUE* args_;
};
Expand Down

0 comments on commit 0e056b4

Please sign in to comment.