From: nobu@... Date: 2005-04-30T21:20:33+09:00 Subject: [ruby-dev:26115] Re: race condition in fixnum..fixnum ? なかだです。 At Sat, 30 Apr 2005 15:00:59 +0900, Tanaka Akira wrote in [ruby-dev:26113]: > とりあえず、スレッドではないかと見当をつけて、 > > Index: eval.c > =================================================================== > RCS file: /src/ruby/eval.c,v > retrieving revision 1.776 > diff -u -p -r1.776 eval.c > --- eval.c 30 Apr 2005 02:59:41 -0000 1.776 > +++ eval.c 30 Apr 2005 05:45:41 -0000 > @@ -3223,6 +3223,7 @@ rb_eval(self, n) > > case NODE_DOT2: > case NODE_DOT3: > + rb_thread_schedule(); > result = rb_range_new(rb_eval(self, node->nd_beg), > rb_eval(self, node->nd_end), > nd_type(node) == NODE_DOT3); ここでコンテキストスイッチが起きることはないはず、と思うんです が。 > で、実際のところどうなんでしょう? > 変更を加えなくても推測した問題は起きうるものでしょうか? 少なくともこれに関しては、rb_eval()よりもparserで処理したほうが 適切のような気がします。 * eval.c (rb_eval), parse.y (arg): reduce fixnum range literal at parser. fixed: [ruby-dev:26113] Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.776 diff -U2 -p -r1.776 eval.c --- eval.c 30 Apr 2005 02:59:41 -0000 1.776 +++ eval.c 30 Apr 2005 12:16:46 -0000 @@ -3227,14 +3227,4 @@ rb_eval(self, n) rb_eval(self, node->nd_end), nd_type(node) == NODE_DOT3); - if (node->nd_state) break; - if (nd_type(node->nd_beg) == NODE_LIT && FIXNUM_P(node->nd_beg->nd_lit) && - nd_type(node->nd_end) == NODE_LIT && FIXNUM_P(node->nd_end->nd_lit)) - { - nd_set_type(node, NODE_LIT); - node->nd_lit = result; - } - else { - node->nd_state = 1; - } break; Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.377 diff -U2 -p -r1.377 parse.y --- parse.y 14 Apr 2005 10:05:27 -0000 1.377 +++ parse.y 30 Apr 2005 12:09:49 -0000 @@ -1761,5 +1761,12 @@ arg : lhs '=' arg value_expr($1); value_expr($3); - $$ = NEW_DOT2($1, $3); + if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) && + nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) { + $1->nd_lit = rb_range_new($1->nd_lit, $3->nd_lit, Qfalse); + $$ = $1; + } + else { + $$ = NEW_DOT2($1, $3); + } /*% $$ = dispatch2(dot2, $1, $3); @@ -1771,5 +1778,12 @@ arg : lhs '=' arg value_expr($1); value_expr($3); - $$ = NEW_DOT3($1, $3); + if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) && + nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) { + $1->nd_lit = rb_range_new($1->nd_lit, $3->nd_lit, Qtrue); + $$ = $1; + } + else { + $$ = NEW_DOT3($1, $3); + } /*% $$ = dispatch2(dot3, $1, $3); -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦