From: nobu.nakada@... Date: 2002-08-11T19:10:10+09:00 Subject: [ruby-dev:17973] Re: line number(Re: Re: [ruby-cvs] ruby: * random.c: replace with Mersenne Twister RNG.) なかだです。 At Sat, 3 Aug 2002 12:51:57 +0900, Nobuyoshi-Nakada wrote: > 実行中のNODE自体を保存しておいて例外のときにnd_lineで取り出すと > いうのを思い付きましたが、ruby_source{file,line}との兼ね合いは > どうだか。 一応[ruby-dev:17886]をコミットしてみたものの、やはり遅くなった ので(2002-08-06比1〜2%)、これを試してみました。2002-08-11版より は速いものの、やっぱりやや遅いです。ちょうど中間くらい。 Index: env.h =================================================================== RCS file: /cvs/ruby/src/ruby/env.h,v retrieving revision 1.8 diff -u -2 -p -r1.8 env.h --- env.h 14 May 2002 06:22:25 -0000 1.8 +++ env.h 11 Aug 2002 08:37:19 -0000 @@ -23,6 +23,5 @@ extern struct FRAME { struct FRAME *prev; struct FRAME *tmp; - char *file; - int line; + struct RNode *node; int iter; int flags; Index: error.c =================================================================== RCS file: /cvs/ruby/src/ruby/error.c,v retrieving revision 1.45 diff -u -2 -p -r1.45 error.c --- error.c 11 Jun 2002 01:27:46 -0000 1.45 +++ error.c 11 Aug 2002 08:33:00 -0000 @@ -41,4 +41,5 @@ err_snprintf(buf, len, fmt, args) int n; + ruby_set_current_source(); if (!ruby_sourcefile) { vsnprintf(buf, len, fmt, args); Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.310 diff -u -2 -p -r1.310 eval.c --- eval.c 11 Aug 2002 00:36:38 -0000 1.310 +++ eval.c 11 Aug 2002 09:48:05 -0000 @@ -120,4 +120,5 @@ static int scope_vmode; #define SCOPE_TEST(f) (scope_vmode&(f)) +NODE* ruby_current_node; int ruby_safe_level = 0; /* safe-level: @@ -526,6 +527,5 @@ static struct SCOPE *top_scope; _frame.prev = ruby_frame; \ _frame.tmp = 0; \ - _frame.file = ruby_sourcefile; \ - _frame.line = ruby_sourceline; \ + _frame.node = ruby_current_node; \ _frame.iter = ruby_iter->iter; \ _frame.cbase = ruby_frame->cbase; \ @@ -536,6 +536,5 @@ static struct SCOPE *top_scope; #define POP_FRAME() \ - ruby_sourcefile = _frame.file; \ - ruby_sourceline = _frame.line; \ + ruby_current_node = _frame.node; \ ruby_frame = _frame.prev; \ } while (0) @@ -588,6 +587,5 @@ new_blktag() _block.frame = *ruby_frame; \ _block.klass = ruby_class; \ - _block.frame.file = ruby_sourcefile;\ - _block.frame.line = ruby_sourceline;\ + _block.frame.node = ruby_current_node;\ _block.scope = ruby_scope; \ _block.prev = ruby_block; \ @@ -888,9 +886,19 @@ static void assign _((VALUE,NODE*,VALUE, static VALUE trace_func = 0; static int tracing = 0; -static void call_trace_func _((char*,char*,int,VALUE,ID,VALUE)); +static void call_trace_func _((char*,NODE*,VALUE,ID,VALUE)); + +void +ruby_set_current_source() +{ + if (ruby_current_node) { + ruby_sourcefile = ruby_current_node->nd_file; + ruby_sourceline = nd_line(ruby_current_node); + } +} static void error_pos() { + ruby_set_current_source(); if (ruby_sourcefile) { if (ruby_frame->last_func) { @@ -941,4 +949,5 @@ error_print() POP_TAG(); if (NIL_P(errat)){ + ruby_set_current_source(); if (ruby_sourcefile) fprintf(stderr, "%s:%d", ruby_sourcefile, ruby_sourceline); @@ -1143,7 +1152,8 @@ error_handle(ex) break; case TAG_THROW: - if (prot_tag && prot_tag->frame && prot_tag->frame->file) { + if (prot_tag && prot_tag->frame && prot_tag->frame->node) { + NODE *tag = prot_tag->frame->node; fprintf(stderr, "%s:%d: uncaught throw\n", - prot_tag->frame->file, prot_tag->frame->line); + tag->nd_file, nd_line(tag)); } else { @@ -1277,9 +1287,10 @@ rb_eval_string(str) { VALUE v; - char *oldsrc = ruby_sourcefile; + NODE *oldsrc = ruby_current_node; + ruby_current_node = 0; ruby_sourcefile = rb_source_filename("(eval)"); v = eval(ruby_top_self, rb_str_new2(str), Qnil, 0, 0); - ruby_sourcefile = oldsrc; + ruby_current_node = oldsrc; return v; @@ -1757,6 +1768,5 @@ copy_node_scope(node, rval) argc=n->nd_alen;\ if (argc > 0) {\ - char *file = ruby_sourcefile;\ - int line = ruby_sourceline;\ + NODE *cnode = ruby_current_node;\ int i;\ n = anode;\ @@ -1766,6 +1776,5 @@ copy_node_scope(node, rval) n=n->nd_next;\ }\ - ruby_sourcefile = file;\ - ruby_sourceline = line;\ + ruby_current_node = cnode;\ }\ else {\ @@ -1776,6 +1785,5 @@ copy_node_scope(node, rval) else {\ VALUE args = rb_eval(self,n);\ - char *file = ruby_sourcefile;\ - int line = ruby_sourceline;\ + NODE *cnode = ruby_current_node;\ if (TYPE(args) != T_ARRAY)\ args = rb_ary_to_ary(args);\ @@ -1783,6 +1791,5 @@ copy_node_scope(node, rval) argv = ALLOCA_N(VALUE, argc);\ MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);\ - ruby_sourcefile = file;\ - ruby_sourceline = line;\ + ruby_current_node = cnode;\ }\ } while (0) @@ -2055,8 +2062,7 @@ set_trace_func(obj, trace) static void -call_trace_func(event, file, line, self, id, klass) +call_trace_func(event, node, self, id, klass) char *event; - char *file; - int line; + NODE *node; VALUE self; ID id; @@ -2065,6 +2071,5 @@ call_trace_func(event, file, line, self, int state; struct FRAME *prev; - char *file_save = ruby_sourcefile; - int line_save = ruby_sourceline; + NODE *node_save = ruby_current_node; VALUE srcfile; @@ -2079,7 +2084,8 @@ call_trace_func(event, file, line, self, ruby_frame->iter = 0; /* blocks not available anyway */ - if (file) { - ruby_frame->line = ruby_sourceline = line; - ruby_frame->file = ruby_sourcefile = file; + if (node) { + ruby_frame->node = ruby_current_node = node; + ruby_sourcefile = node->nd_file; + ruby_sourceline = nd_line(node); } if (klass) { @@ -2106,6 +2112,5 @@ call_trace_func(event, file, line, self, tracing = 0; - ruby_sourceline = line_save; - ruby_sourcefile = file_save; + ruby_current_node = node_save; if (state) JUMP_TAG(state); } @@ -2210,5 +2215,5 @@ rb_eval(self, n) if (!node) RETURN(Qnil); - ruby_sourceline = nd_line(node); + ruby_current_node = node; switch (nd_type(node)) { case NODE_BLOCK: @@ -2297,5 +2302,5 @@ rb_eval(self, n) case NODE_IF: if (trace_func) { - call_trace_func("line", node->nd_file, ruby_sourceline, self, + call_trace_func("line", node, self, ruby_frame->last_func, ruby_frame->last_class); @@ -2317,10 +2322,8 @@ rb_eval(self, n) while (tag) { if (trace_func) { - call_trace_func("line", tag->nd_file, nd_line(tag), self, + call_trace_func("line", tag, self, ruby_frame->last_func, ruby_frame->last_class); } - ruby_sourcefile = tag->nd_file; - ruby_sourceline = nd_line(tag); if (nd_type(tag->nd_head) == NODE_WHEN) { VALUE v = rb_eval(self, tag->nd_head->nd_head); @@ -2362,10 +2365,8 @@ rb_eval(self, n) while (tag) { if (trace_func) { - call_trace_func("line", tag->nd_file, nd_line(tag), self, + call_trace_func("line", tag, self, ruby_frame->last_func, ruby_frame->last_class); } - ruby_sourcefile = tag->nd_file; - ruby_sourceline = nd_line(tag); if (nd_type(tag->nd_head) == NODE_WHEN) { VALUE v = rb_eval(self, tag->nd_head->nd_head); @@ -2476,6 +2477,4 @@ rb_eval(self, n) else { VALUE recv; - char *file = ruby_sourcefile; - int line = ruby_sourceline; _block.flags &= ~BLOCK_D_SCOPE; @@ -2483,6 +2482,5 @@ rb_eval(self, n) recv = rb_eval(self, node->nd_iter); END_CALLARGS; - ruby_sourcefile = file; - ruby_sourceline = line; + ruby_current_node = node; result = rb_call(CLASS_OF(recv),recv,each,0,0,0); } @@ -2579,6 +2577,6 @@ rb_eval(self, n) NODE * volatile resq = node->nd_resq; - ruby_sourceline = nd_line(node); while (resq) { + ruby_current_node = resq; if (handle_rescue(self, resq)) { state = 0; @@ -3385,5 +3383,5 @@ rb_eval(self, n) ruby_sourceline = node->nd_nth; if (trace_func) { - call_trace_func("line", ruby_sourcefile, ruby_sourceline, self, + call_trace_func("line", node, self, ruby_frame->last_func, ruby_frame->last_class); @@ -3409,6 +3407,5 @@ module_setup(module, n) struct FRAME frame; VALUE result; /* OK */ - char *file = ruby_sourcefile; - int line = ruby_sourceline; + NODE * cnode = ruby_current_node; TMP_PROTECT; @@ -3439,5 +3436,5 @@ module_setup(module, n) if ((state = EXEC_TAG()) == 0) { if (trace_func) { - call_trace_func("class", file, line, ruby_class, + call_trace_func("class", cnode, ruby_class, ruby_frame->last_func, ruby_frame->last_class); @@ -3453,5 +3450,5 @@ module_setup(module, n) ruby_frame = frame.tmp; if (trace_func) { - call_trace_func("end", file, line, 0, + call_trace_func("end", cnode, 0, ruby_frame->last_func, ruby_frame->last_class); } @@ -3603,4 +3600,5 @@ rb_longjmp(tag, mesg) StringValue(e); + ruby_set_current_source(); fprintf(stderr, "Exception `%s' at %s:%d - %s\n", rb_class2name(CLASS_OF(ruby_errinfo)), @@ -3611,5 +3609,5 @@ rb_longjmp(tag, mesg) rb_trap_restore_mask(); if (trace_func && tag != TAG_FATAL) { - call_trace_func("raise", ruby_sourcefile, ruby_sourceline, + call_trace_func("raise", ruby_current_node, ruby_frame->self, ruby_frame->last_func, @@ -3737,6 +3735,5 @@ rb_yield_0(val, self, klass, pcall) struct SCOPE * volatile old_scope; struct FRAME frame; - char *const file = ruby_sourcefile; - int line = ruby_sourceline; + NODE *cnode = ruby_current_node; int state; static unsigned serial = 1; @@ -3863,6 +3860,5 @@ rb_yield_0(val, self, klass, pcall) scope_dup(old_scope); ruby_scope = old_scope; - ruby_sourcefile = file; - ruby_sourceline = line; + ruby_current_node = cnode; if (state) { if (!block->tag) { @@ -4271,6 +4267,5 @@ rb_f_missing(argc, argv, obj) char *format = 0; char *desc = ""; - char *file = ruby_sourcefile; - int line = ruby_sourceline; + NODE *cnode = ruby_current_node; if (argc == 0 || !SYMBOL_P(argv[0])) { @@ -4324,6 +4319,5 @@ rb_f_missing(argc, argv, obj) } - ruby_sourcefile = file; - ruby_sourceline = line; + ruby_current_node = cnode; PUSH_FRAME(); /* fake frame */ *ruby_frame = *_frame.prev->prev; @@ -4507,12 +4501,10 @@ rb_call0(klass, recv, id, argc, argv, bo if (trace_func) { int state; - char *file = ruby_frame->prev->file; - int line = ruby_frame->prev->line; - if (!file) { - file = ruby_sourcefile; - line = ruby_sourceline; + NODE *cnode = ruby_frame->prev->node; + if (!cnode) { + cnode = ruby_current_node; } - call_trace_func("c-call", 0, 0, recv, id, klass); + call_trace_func("c-call", 0, recv, id, klass); PUSH_TAG(PROT_FUNC); if ((state = EXEC_TAG()) == 0) { @@ -4520,5 +4512,5 @@ rb_call0(klass, recv, id, argc, argv, bo } POP_TAG(); - call_trace_func("c-return", 0, 0, recv, id, klass); + call_trace_func("c-return", 0, recv, id, klass); if (state) JUMP_TAG(state); } @@ -4630,6 +4622,4 @@ rb_call0(klass, recv, id, argc, argv, bo } if (opt) { - ruby_sourcefile = opt->nd_file; - ruby_sourceline = nd_line(opt); rb_eval(recv, opt); } @@ -4649,6 +4639,5 @@ rb_call0(klass, recv, id, argc, argv, bo if (trace_func) { - call_trace_func("call", b2->nd_file, nd_line(b2), - recv, id, klass); + call_trace_func("call", b2, recv, id, klass); } result = rb_eval(recv, body); @@ -4663,11 +4652,9 @@ rb_call0(klass, recv, id, argc, argv, bo ruby_cref = saved_cref; if (trace_func) { - char *file = ruby_frame->prev->file; - int line = ruby_frame->prev->line; - if (!file) { - file = ruby_sourcefile; - line = ruby_sourceline; + NODE *cnode = ruby_frame->prev->node; + if (!cnode) { + cnode = ruby_current_node; } - call_trace_func("return", file, line, recv, id, klass); + call_trace_func("return", cnode, recv, id, klass); } switch (state) { @@ -4873,7 +4860,9 @@ backtrace(lev) char buf[BUFSIZ]; VALUE ary; + NODE *n; ary = rb_ary_new(); if (lev < 0) { + ruby_set_current_source(); if (frame->last_func) { snprintf(buf, BUFSIZ, "%s:%d:in `%s'", @@ -4898,12 +4887,12 @@ backtrace(lev) } } - while (frame && frame->file) { + while (frame && (n = frame->node)) { if (frame->prev && frame->prev->last_func) { snprintf(buf, BUFSIZ, "%s:%d:in `%s'", - frame->file, frame->line, + n->nd_file, nd_line(n), rb_id2name(frame->prev->last_func)); } else { - snprintf(buf, BUFSIZ, "%s:%d", frame->file, frame->line); + snprintf(buf, BUFSIZ, "%s:%d", n->nd_file, nd_line(n)); } rb_ary_push(ary, rb_str_new2(buf)); @@ -4986,6 +4975,5 @@ eval(self, src, scope, file, line) volatile VALUE old_wrapper; struct FRAME frame; - char *filesave = ruby_sourcefile; - int linesave = ruby_sourceline; + NODE *nodesave = ruby_current_node; volatile int iter = ruby_frame->iter; int state; @@ -5029,4 +5017,6 @@ eval(self, src, scope, file, line) } if (file == 0) { + ruby_set_current_source(); + ruby_current_node = 0; file = ruby_sourcefile; line = ruby_sourceline; @@ -5089,6 +5079,5 @@ eval(self, src, scope, file, line) ruby_frame->iter = iter; } - ruby_sourcefile = filesave; - ruby_sourceline = linesave; + ruby_current_node = nodesave; if (state) { if (state == TAG_RAISE) { @@ -7264,6 +7253,5 @@ struct thread { int flags; /* misc. states (vmode/rb_trap_immediate/raised) */ - char *file; - int line; + NODE *node; int tracing; @@ -7463,6 +7451,5 @@ static VALUE rb_thread_raise _((int, VAL static int th_raise_argc; static VALUE th_raise_argv[2]; -static char *th_raise_file; -static int th_raise_line; +static NODE *th_raise_node; static VALUE th_cmd; static int th_sig; @@ -7520,6 +7507,5 @@ rb_thread_save_context(th) th->safe = ruby_safe_level; - th->file = ruby_sourcefile; - th->line = ruby_sourceline; + th->node = ruby_current_node; } @@ -7543,6 +7529,5 @@ thread_switch(n) case RESTORE_RAISE: ruby_frame->last_func = 0; - ruby_sourcefile = th_raise_file; - ruby_sourceline = th_raise_line; + ruby_current_node = th_raise_node; rb_f_raise(th_raise_argc, th_raise_argv); break; @@ -7610,6 +7595,5 @@ rb_thread_restore_context(th, exit) ruby_safe_level = th->safe; - ruby_sourcefile = th->file; - ruby_sourceline = th->line; + ruby_current_node = th->node; tmp = th; @@ -7682,6 +7666,5 @@ rb_thread_deadlock() th_raise_argc = 1; th_raise_argv[0] = rb_exc_new2(rb_eFatal, "Thread: deadlock"); - th_raise_file = ruby_sourcefile; - th_raise_line = ruby_sourceline; + th_raise_node = ruby_current_node; rb_thread_restore_context(main_thread, RESTORE_RAISE); } @@ -7947,11 +7930,10 @@ rb_thread_schedule() if (!next) { /* raise fatal error to main thread */ - curr_thread->file = ruby_sourcefile; - curr_thread->line = ruby_sourceline; + curr_thread->node = ruby_current_node; FOREACH_THREAD_FROM(curr, th) { fprintf(stderr, "deadlock 0x%lx: %d:%d %s - %s:%d\n", th->thread, th->status, th->wait_for, th==main_thread ? "(main)" : "", - th->file, th->line); + th->node->nd_file, nd_line(th->node)); } END_FOREACH_FROM(curr, th); @@ -8929,6 +8911,5 @@ rb_thread_raise(argc, argv, th) th_raise_argc = argc; - th_raise_file = ruby_sourcefile; - th_raise_line = ruby_sourceline; + th_raise_node = ruby_current_node; rb_thread_restore_context(curr_thread, RESTORE_RAISE); return Qnil; /* not reached */ Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.204 diff -u -2 -p -r1.204 parse.y --- parse.y 1 Aug 2002 09:42:36 -0000 1.204 +++ parse.y 11 Aug 2002 09:22:54 -0000 @@ -2337,4 +2337,6 @@ int ruby__end__seen; static VALUE ruby_debug_lines; +EXTERN NODE* ruby_current_node; + static NODE* yycompile(f, line) @@ -2373,4 +2375,5 @@ yycompile(f, line) lex_strnest = 0; quoted_term = -1; + ruby_current_node = 0; ruby_sourcefile = rb_source_filename(f); ruby_in_compile = 1; -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦