ext/bindex/cruby.c in bindex-0.2.0 vs ext/bindex/cruby.c in bindex-0.3.0

- old
+ new

@@ -1,29 +1,57 @@ -#include "bindex.h" +#include <ruby.h> +#include <ruby/debug.h> VALUE bx_mBindex; static VALUE -bx_current_bindings(VALUE self) +current_bindings_callback(const rb_debug_inspector_t *context, void *data) { - return current_bindings(); + VALUE locations = rb_debug_inspector_backtrace_locations(context); + VALUE binding, bindings = rb_ary_new(); + long i, length = RARRAY_LEN(locations); + + for (i = 0; i < length; i++) { + binding = rb_debug_inspector_frame_binding_get(context, i); + + if (!NIL_P(binding)) { + rb_ary_push(bindings, binding); + } + } + + return bindings; } -static VALUE -bx_exc_set_backtrace(VALUE self, VALUE bt) +VALUE +current_bindings(void) { - /* rb_check_backtrace can raise an exception, if the input arguments are not - * to its likings. Set the bindings afterwards, so we don't waste when not - * needed. */ - VALUE backtrace = rb_iv_set(self, "bt", rb_check_backtrace(bt)); + return rb_debug_inspector_open(current_bindings_callback, NULL); +} - rb_iv_set(self, "bindings", current_bindings()); +static void +set_exception_bindings_callback(VALUE tpval, void *data) +{ + rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(tpval); + VALUE exception = rb_tracearg_raised_exception(trace_arg); - return backtrace; + rb_iv_set(exception, "bindings", current_bindings()); } +void +set_exception_bindings_on_raise(void) +{ + VALUE tpval = rb_tracepoint_new(0, RUBY_EVENT_RAISE, set_exception_bindings_callback, 0); + rb_tracepoint_enable(tpval); +} + static VALUE +bx_current_bindings(VALUE self) +{ + return current_bindings(); +} + +static VALUE bx_exc_bindings(VALUE self) { VALUE bindings; bindings = rb_iv_get(self, "bindings"); @@ -38,9 +66,9 @@ Init_cruby(void) { bx_mBindex = rb_define_module("Bindex"); rb_define_singleton_method(bx_mBindex, "current_bindings", bx_current_bindings, 0); - - rb_define_method(rb_eException, "set_backtrace", bx_exc_set_backtrace, 1); rb_define_method(rb_eException, "bindings", bx_exc_bindings, 0); + + set_exception_bindings_on_raise(); }