static void call_trace_func(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klass) { const char *srcfile = rb_sourcefile(); VALUE eventname = rb_str_new2(get_event_name(event)); VALUE filename = srcfile ? rb_str_new2(srcfile) : Qnil; VALUE argv[6]; int line = rb_sourceline(); rb_thread_t *th = GET_THREAD(); if (!klass) { rb_thread_method_id_and_class(th, &id, &klass); } if (klass) { if (RB_TYPE_P(klass, T_ICLASS)) { klass = RBASIC(klass)->klass; } else if (FL_TEST(klass, FL_SINGLETON)) { klass = rb_iv_get(klass, "__attached__"); } } argv[0] = eventname; argv[1] = filename; argv[2] = INT2FIX(line); argv[3] = id ? ID2SYM(id) : Qnil; argv[4] = (self && srcfile) ? rb_binding_new() : Qnil; argv[5] = klass ? klass : Qnil; rb_proc_call_with_block(proc, 6, argv, Qnil); }
static VALUE create_proc(VALUE klass, VALUE binding, rb_iseq_t * iseq) { VALUE new_proc; rb_proc_t * p; if(binding == Qnil) { binding = rb_binding_new(); } new_proc = rb_funcall( rb_cObject, rb_intern("eval"), 2, rb_str_new2("proc { }"), binding); GetProcPtr(new_proc, p); p->block.iseq = iseq; RBASIC(new_proc)->klass = klass; return new_proc; }
/** * line_trace_callback * Callback function for thread line event tracing. It checks Tracer#breakpoints_cache * for any breakpoints trigger on current line called. Then trigger evaluation * procedure if found matching breakpoints. It also skip breakpoints that are * already marked completed. */ static void line_trace_callback(rb_event_flag_t event, VALUE data, VALUE obj, ID mid, VALUE klass) { VALUE self = data; VALUE trace_path; int c_trace_lineno; const char *c_trace_path; VALUE trace_binding; VALUE call_stack_bindings; ID callers_id; ID breakpoints_hit_id; VALUE matching_result; c_trace_path = rb_sourcefile(); // Ensure C_trace_path is absolute path trace_path = rb_str_new_cstr(c_trace_path); trace_path = rb_file_expand_path(trace_path, Qnil); if(!RTEST(trace_path)) { return; } c_trace_path = rb_string_value_cstr(&trace_path); c_trace_lineno = rb_sourceline(); matching_result = match_breakpoints(self, c_trace_path, c_trace_lineno); CONST_ID(callers_id, "callers"); CONST_ID(breakpoints_hit_id, "breakpoints_hit"); // If matching result isn't an array, it means we're in completely wrong file, // or not on the right line. Turn line tracing off if we're in wrong file. if (!RB_TYPE_P(matching_result, T_ARRAY)) { if (!RTEST(matching_result)) { disable_line_trace_for_thread(Qnil); } return; } trace_binding = rb_binding_new(); call_stack_bindings = rb_funcall(trace_binding, callers_id, 0); rb_funcall(self, breakpoints_hit_id, 2, matching_result, call_stack_bindings); return; }
static VALUE rb_f_binding(VALUE self) { return rb_binding_new(); }