1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
#include "ruby.h"
#include "rubyspec.h"
#include "ruby/debug.h"
#ifdef __cplusplus
extern "C" {
#endif
static VALUE callback_data = Qfalse;
static VALUE rb_debug_inspector_open_callback(const rb_debug_inspector_t *dc, void *ptr) {
if (!dc) {
rb_raise(rb_eRuntimeError, "rb_debug_inspector_t should not be NULL");
}
VALUE locations = rb_debug_inspector_backtrace_locations(dc);
int len = RARRAY_LENINT(locations);
VALUE results = rb_ary_new2(len);
for (int i = 0; i < len; i++) {
VALUE ary = rb_ary_new2(5); // [self, klass, binding, iseq, backtrace_location]
rb_ary_store(ary, 0, rb_debug_inspector_frame_self_get(dc, i));
rb_ary_store(ary, 1, rb_debug_inspector_frame_class_get(dc, i));
rb_ary_store(ary, 2, rb_debug_inspector_frame_binding_get(dc, i));
rb_ary_store(ary, 3, rb_debug_inspector_frame_iseq_get(dc, i));
rb_ary_store(ary, 4, rb_ary_entry(locations, i));
rb_ary_push(results, ary);
}
callback_data = (VALUE)ptr;
return results;
}
static VALUE rb_debug_inspector_frame_self_get_callback(const rb_debug_inspector_t *dc, void *ptr) {
return rb_debug_inspector_frame_self_get(dc, NUM2LONG((VALUE) ptr));
}
static VALUE rb_debug_inspector_frame_class_get_callback(const rb_debug_inspector_t *dc, void *ptr) {
return rb_debug_inspector_frame_class_get(dc, NUM2LONG((VALUE) ptr));
}
static VALUE rb_debug_inspector_frame_binding_get_callback(const rb_debug_inspector_t *dc, void *ptr) {
return rb_debug_inspector_frame_binding_get(dc, NUM2LONG((VALUE) ptr));
}
static VALUE rb_debug_inspector_frame_iseq_get_callback(const rb_debug_inspector_t *dc, void *ptr) {
return rb_debug_inspector_frame_iseq_get(dc, NUM2LONG((VALUE) ptr));
}
static VALUE debug_spec_callback_data(VALUE self) {
return callback_data;
}
VALUE debug_spec_rb_debug_inspector_open(VALUE self, VALUE index) {
return rb_debug_inspector_open(rb_debug_inspector_open_callback, (void *)index);
}
VALUE debug_spec_rb_debug_inspector_frame_self_get(VALUE self, VALUE index) {
return rb_debug_inspector_open(rb_debug_inspector_frame_self_get_callback, (void *)index);
}
VALUE debug_spec_rb_debug_inspector_frame_class_get(VALUE self, VALUE index) {
return rb_debug_inspector_open(rb_debug_inspector_frame_class_get_callback, (void *)index);
}
VALUE debug_spec_rb_debug_inspector_frame_binding_get(VALUE self, VALUE index) {
return rb_debug_inspector_open(rb_debug_inspector_frame_binding_get_callback, (void *)index);
}
VALUE debug_spec_rb_debug_inspector_frame_iseq_get(VALUE self, VALUE index) {
return rb_debug_inspector_open(rb_debug_inspector_frame_iseq_get_callback, (void *)index);
}
static VALUE rb_debug_inspector_backtrace_locations_func(const rb_debug_inspector_t *dc, void *ptr) {
return rb_debug_inspector_backtrace_locations(dc);
}
VALUE debug_spec_rb_debug_inspector_backtrace_locations(VALUE self) {
return rb_debug_inspector_open(rb_debug_inspector_backtrace_locations_func, (void *)self);
}
void Init_debug_spec(void) {
VALUE cls = rb_define_class("CApiDebugSpecs", rb_cObject);
rb_define_method(cls, "rb_debug_inspector_open", debug_spec_rb_debug_inspector_open, 1);
rb_define_method(cls, "rb_debug_inspector_frame_self_get", debug_spec_rb_debug_inspector_frame_self_get, 1);
rb_define_method(cls, "rb_debug_inspector_frame_class_get", debug_spec_rb_debug_inspector_frame_class_get, 1);
rb_define_method(cls, "rb_debug_inspector_frame_binding_get", debug_spec_rb_debug_inspector_frame_binding_get, 1);
rb_define_method(cls, "rb_debug_inspector_frame_iseq_get", debug_spec_rb_debug_inspector_frame_iseq_get, 1);
rb_define_method(cls, "rb_debug_inspector_backtrace_locations", debug_spec_rb_debug_inspector_backtrace_locations, 0);
rb_define_method(cls, "debug_spec_callback_data", debug_spec_callback_data, 0);
}
#ifdef __cplusplus
}
#endif
|