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