summaryrefslogtreecommitdiff
path: root/spec/ruby/optional/capi/ext/debug_spec.c
blob: 344dfc33fab80baf70fe743ad5e3d4ec030d9855 (plain)
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