File: debug_inspector.c

package info (click to toggle)
ruby-debug-inspector 1.1.0%2Bgh-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 144 kB
  • sloc: ansic: 90; ruby: 68; sh: 4; makefile: 4
file content (117 lines) | stat: -rw-r--r-- 3,025 bytes parent folder | download | duplicates (2)
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**********************************************************************

  debug_inspector.c

  $Author: ko1 $
  created at: Thu Nov 15 17:34:36 2012

  Copyright (C) 1993-2012 Yukihiro Matsumoto

**********************************************************************/

#include "ruby/ruby.h"
#include "ruby/debug.h"

static size_t
di_size(const void *dummy)
{
    return sizeof(void *);
}

static const rb_data_type_t di_data_type = {
    "simple_debugger",
    {0, 0, di_size,},
};

static const rb_debug_inspector_t *
di_get_dc(VALUE self)
{
    const rb_debug_inspector_t *dc;
    TypedData_Get_Struct(self, const rb_debug_inspector_t, &di_data_type, dc);
    if (dc == 0) {
	rb_raise(rb_eArgError, "invalid debug context");
    }
    return dc;
}

static VALUE
di_backtrace_locations(VALUE self)
{
    const rb_debug_inspector_t *dc = di_get_dc(self);
    return rb_debug_inspector_backtrace_locations(dc);
}

static VALUE
di_binding(VALUE self, VALUE index)
{
    const rb_debug_inspector_t *dc = di_get_dc(self);
    return rb_debug_inspector_frame_binding_get(dc, NUM2INT(index));
}

static VALUE
di_frame_class(VALUE self, VALUE index)
{
    const rb_debug_inspector_t *dc = di_get_dc(self);
    return rb_debug_inspector_frame_class_get(dc, NUM2INT(index));
}

static VALUE
di_frame_iseq(VALUE self, VALUE index)
{
    const rb_debug_inspector_t *dc = di_get_dc(self);
    return rb_debug_inspector_frame_iseq_get(dc, NUM2INT(index));
}

static VALUE
di_frame_self(VALUE self, VALUE index)
{
    const rb_debug_inspector_t *dc = di_get_dc(self);
    return rb_debug_inspector_frame_self_get(dc, NUM2INT(index));
}

static VALUE
breakpoint_i(const rb_debug_inspector_t *dc, void *ptr)
{
    VALUE self = (VALUE)ptr;
    VALUE result;

    /* should protect */
    DATA_PTR(self) = (void *)dc;
    result = rb_yield(self);
    return result;
}

static VALUE
di_open_body(VALUE self)
{
    return rb_debug_inspector_open(breakpoint_i, (void *)self);
}

static VALUE
di_open_ensure(VALUE self)
{
    DATA_PTR(self) = 0;
    return self;
}

static VALUE
di_open_s(VALUE klass)
{
    VALUE self = TypedData_Wrap_Struct(klass, &di_data_type, 0);
    return rb_ensure(di_open_body, self, di_open_ensure, self);
}

void
Init_debug_inspector(void)
{
    VALUE rb_cRubyVM = rb_const_get(rb_cObject, rb_intern("RubyVM"));
    VALUE cDebugInspector = rb_define_class_under(rb_cRubyVM, "DebugInspector", rb_cObject);
    
    rb_undef_alloc_func(cDebugInspector);
    rb_define_singleton_method(cDebugInspector, "open", di_open_s, 0);
    rb_define_method(cDebugInspector, "backtrace_locations", di_backtrace_locations, 0);
    rb_define_method(cDebugInspector, "frame_binding", di_binding, 1);
    rb_define_method(cDebugInspector, "frame_class", di_frame_class, 1);
    rb_define_method(cDebugInspector, "frame_iseq", di_frame_iseq, 1);
    rb_define_method(cDebugInspector, "frame_self", di_frame_self, 1);
}