Index: eval.c =================================================================== --- eval.c (revision 25242) +++ eval.c (working copy) @@ -753,4 +753,5 @@ rb_attr(klass, id, read, write, ex) rb_raise(rb_eArgError, "argument needs to be symbol or string"); } + ruby_set_current_source(); len = strlen(name)+2; buf = ALLOCA_N(char,len); @@ -1204,4 +1205,5 @@ static void call_trace_func _((rb_event_ #define SET_CURRENT_SOURCE() ((void)0) #endif +#define SET_CURRENT_NODE(node) (ruby_current_node = (node), SET_CURRENT_SOURCE()) void @@ -1753,5 +1755,5 @@ rb_eval_string(str) ruby_sourcefile = rb_source_filename("(eval)"); v = eval(ruby_top_self, rb_str_new2(str), Qnil, 0, 0); - ruby_current_node = oldsrc; + SET_CURRENT_NODE(oldsrc); return v; @@ -2297,5 +2299,5 @@ rb_copy_node_scope(node, rval) NODE *rval; { - NODE *copy = NEW_NODE(NODE_SCOPE,0,rval,node->nd_next); + NODE *copy = (ruby_set_current_source(), NEW_NODE(NODE_SCOPE,0,rval,node->nd_next)); if (node->nd_tbl) { @@ -2818,6 +2820,5 @@ call_trace_func(event, node, self, id, k tracing = 0; - ruby_current_node = node_save; - SET_CURRENT_SOURCE(); + SET_CURRENT_NODE(node_save); if (state) JUMP_TAG(state); } @@ -3016,5 +3017,6 @@ rb_eval(self, n) if (!node) RETURN(Qnil); - ruby_current_node = node; + SET_CURRENT_NODE(node); + switch (nd_type(node)) { case NODE_BLOCK: @@ -3290,6 +3292,5 @@ rb_eval(self, n) recv = rb_eval(self, node->nd_iter); END_CALLARGS; - ruby_current_node = node; - SET_CURRENT_SOURCE(); + SET_CURRENT_NODE(node); result = rb_call(CLASS_OF(recv),recv,each,0,0,0,self); } @@ -3350,10 +3351,9 @@ rb_eval(self, n) if (node->nd_head) { result = rb_eval(self, node->nd_head); - ruby_current_node = node; + SET_CURRENT_NODE(node); } else { result = Qundef; /* no arg */ } - SET_CURRENT_SOURCE(); result = rb_yield_0(result, 0, 0, 0, node->nd_state); break; @@ -3387,5 +3387,5 @@ rb_eval(self, n) rescuing = -1; while (resq) { - ruby_current_node = resq; + SET_CURRENT_NODE(resq); if (handle_rescue(self, resq)) { state = 0; @@ -3533,6 +3533,5 @@ rb_eval(self, n) END_CALLARGS; - ruby_current_node = node; - SET_CURRENT_SOURCE(); + SET_CURRENT_NODE(node); rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,scope,self); result = argv[argc-1]; @@ -3551,6 +3550,5 @@ rb_eval(self, n) END_CALLARGS; - ruby_current_node = node; - SET_CURRENT_SOURCE(); + SET_CURRENT_NODE(node); result = rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0,self); } @@ -3566,6 +3564,5 @@ rb_eval(self, n) END_CALLARGS; - ruby_current_node = node; - SET_CURRENT_SOURCE(); + SET_CURRENT_NODE(node); result = rb_call(CLASS_OF(self),self,node->nd_mid,argc,argv,1,self); } @@ -3573,5 +3570,4 @@ rb_eval(self, n) case NODE_VCALL: - SET_CURRENT_SOURCE(); result = rb_call(CLASS_OF(self),self,node->nd_mid,0,0,2,self); break; @@ -3624,8 +3620,7 @@ rb_eval(self, n) SETUP_ARGS(node->nd_args); END_CALLARGS; - ruby_current_node = node; + SET_CURRENT_NODE(node); } - SET_CURRENT_SOURCE(); result = rb_call_super(argc, argv); } @@ -5103,5 +5098,5 @@ rb_yield_0(val, self, klass, flags, aval rb_warn("multiple values for a block parameter (%d for 1)\n\tfrom %s:%d", len, cnode->nd_file, nd_line(cnode)); - ruby_current_node = cnode; + SET_CURRENT_NODE(cnode); } } @@ -5124,5 +5119,5 @@ rb_yield_0(val, self, klass, flags, aval goto pop_state; } - ruby_current_node = node; + SET_CURRENT_NODE(node); PUSH_ITER(block->iter); @@ -5228,5 +5223,5 @@ rb_yield_0(val, self, klass, flags, aval break; } - ruby_current_node = cnode; + SET_CURRENT_NODE(cnode); return result; } @@ -5367,5 +5362,5 @@ assign(self, lhs, val, pcall) int pcall; { - ruby_current_node = lhs; + SET_CURRENT_NODE(lhs); if (val == Qundef) { rb_warning("assigning void value"); @@ -5434,6 +5429,5 @@ assign(self, lhs, val, pcall) if (!lhs->nd_args) { /* attr set */ - ruby_current_node = lhs; - SET_CURRENT_SOURCE(); + SET_CURRENT_NODE(lhs); rb_call(CLASS_OF(recv), recv, lhs->nd_mid, 1, &val, scope, self); } @@ -5444,6 +5438,5 @@ assign(self, lhs, val, pcall) args = rb_eval(self, lhs->nd_args); rb_ary_push(args, val); - ruby_current_node = lhs; - SET_CURRENT_SOURCE(); + SET_CURRENT_NODE(lhs); rb_call(CLASS_OF(recv), recv, lhs->nd_mid, RARRAY(args)->len, RARRAY(args)->ptr, scope, self); @@ -5764,5 +5757,5 @@ rb_method_missing(argc, argv, obj) } - ruby_current_node = cnode; + SET_CURRENT_NODE(cnode); { int n = 0; @@ -10094,4 +10087,5 @@ rb_mod_define_method(argc, argv, mod) rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); } + ruby_set_current_source(); if (RDATA(body)->dmark == (RUBY_DATA_FUNC)bm_mark) { node = NEW_DMETHOD(method_unbind(body)); @@ -10126,4 +10120,54 @@ rb_mod_define_method(argc, argv, mod) /* + * call-seq: + * prc.source_location => [String, Fixnum] + * + * returns the ruby source filename and line number containing this proc + * or nil if this proc was not defined in ruby (i.e. native) + */ + +VALUE +rb_proc_location(VALUE self) +{ + struct BLOCK *data; + NODE *node; + + Data_Get_Struct(self, struct BLOCK, data); + if ((node = data->frame.node) || (node = data->body)) { + const char *filename = node->nd_file; + int lineno = nd_line(node); + if (filename) { + return rb_assoc_new(rb_str_new2(filename), INT2FIX(lineno)); + } + } + return Qnil; +} + +/* + * call-seq: + * meth.source_location => [String, Fixnum] + * + * returns the ruby source filename and line number containing this method + * or nil if this method was not defined in ruby (i.e. native) + */ + +VALUE +rb_method_location(VALUE method) +{ + struct METHOD *data; + NODE *node; + + Data_Get_Struct(method, struct METHOD, data); + if (node = data->body) { + const char *filename = node->nd_file; + int lineno = nd_line(node); + if (filename) { + return rb_assoc_new(rb_str_new2(filename), INT2FIX(lineno)); + } + } + return Qnil; +} + +/* * Proc objects are blocks of code that have been bound to * a set of local variables. Once bound, the code may be called in @@ -10177,4 +10221,5 @@ Init_Proc() rb_define_method(rb_cProc, "to_proc", proc_to_self, 0); rb_define_method(rb_cProc, "binding", proc_binding, 0); + rb_define_method(rb_cProc, "source_location", rb_proc_location, 0); rb_define_global_function("proc", proc_lambda, 0); @@ -10197,4 +10242,5 @@ Init_Proc() rb_define_method(rb_cMethod, "unbind", method_unbind, 0); rb_define_method(rb_mKernel, "method", rb_obj_method, 1); + rb_define_method(rb_cMethod, "source_location", rb_method_location, 0); rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject); @@ -10209,4 +10255,5 @@ Init_Proc() rb_define_method(rb_cUnboundMethod, "owner", method_owner, 0); rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1); + rb_define_method(rb_cUnboundMethod, "source_location", rb_method_location, 0); rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1); }