From: matz@... (Yukihiro Matsumoto) Date: 1999-08-07T03:17:13+09:00 Subject: [ruby-dev:7555] Re: make test failure on sunos まつもと ゆきひろです In message "[ruby-dev:7553] make test failure on sunos" on 99/08/06, Katsuyuki Komatsu writes: |ruby-1.3.7ですが、SunOS 4.1.4でmake testが失敗してしまいました。 多分、分かったと思います。bindingで保存したstack上のframe情 報が場合によって解放されちゃう場合があるからでした。GCのタイ ミングで起きたり起きなかったりするわけですね。 こんな感じの修正で起きなくなりそうな気がします。 確認して頂けると嬉しいです。 --- /tmp/eval.c Sat Aug 7 03:15:09 1999 +++ eval.c Sat Aug 7 03:12:10 1999 @@ -406,2 +406,3 @@ _frame.argc = 0; \ + _frame.argv = 0; \ ruby_frame = &_frame; \ @@ -2214,3 +2215,6 @@ { - VALUE save = ruby_frame->cbase; + struct FRAME frame = *ruby_frame; + + frame.tmp = ruby_frame; + ruby_frame = &frame; @@ -2235,3 +2239,3 @@ POP_SCOPE(); - ruby_frame->cbase = save; + ruby_frame = frame.tmp; if (state) JUMP_TAG(state); @@ -2849,3 +2853,3 @@ int state; - VALUE save = ruby_frame->cbase; + struct FRAME frame = *ruby_frame; VALUE result; /* OK */ @@ -2855,2 +2859,5 @@ + frame.tmp = ruby_frame; + ruby_frame = &frame; + /* fill c-ref */ @@ -2890,3 +2897,3 @@ - ruby_frame->cbase = save; + ruby_frame = frame.tmp; if (trace_func) { @@ -4201,3 +4208,2 @@ int volatile old_vmode; - struct FRAME * volatile old_frame; struct FRAME frame; @@ -4223,3 +4229,2 @@ frame.tmp = ruby_frame; /* gc protection */ - old_frame = ruby_frame; ruby_frame = &(frame); @@ -4261,3 +4266,3 @@ if (!NIL_P(scope)) { - ruby_frame = old_frame; + ruby_frame = frame.tmp; if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) @@ -5326,6 +5331,16 @@ { - struct BLOCK *tmp; + struct FRAME *frame; + void *tmp; + frame = data->frame.prev; + while (frame) { + if (frame->argc > 0) + free(frame->argv); + tmp = frame; + frame = frame->prev; + free(tmp); + } while (data) { - free(data->frame.argv); + if (data->frame.argc > 0) + free(data->frame.argv); tmp = data; @@ -5345,5 +5360,7 @@ MEMCPY(tmp, block->prev, struct BLOCK, 1); - tmp->frame.argv = ALLOC_N(VALUE, tmp->frame.argc); + if (tmp->frame.argc > 0) { + tmp->frame.argv = ALLOC_N(VALUE, tmp->frame.argc); + MEMCPY(tmp->frame.argv, block->frame.argv, VALUE, tmp->frame.argc); + } scope_dup(tmp->scope); - MEMCPY(tmp->frame.argv, block->frame.argv, VALUE, tmp->frame.argc); block->prev = tmp; @@ -5353,2 +5370,22 @@ +static void +frame_dup(frame) + struct FRAME *frame; +{ + VALUE *argv; + struct FRAME *tmp; + + for (;;) { + if (frame->argc > 0) { + argv = ALLOC_N(VALUE, frame->argc); + MEMCPY(argv, frame->argv, VALUE, frame->argc); + frame->argv = argv; + } + if (!frame->prev) break; + tmp = ALLOC(struct FRAME); + *tmp = *frame->prev; + frame->prev = tmp; + frame = tmp; + } +} @@ -5365,4 +5402,3 @@ MEMCPY(data, orig, struct BLOCK, 1); - data->frame.argv = ALLOC_N(VALUE, orig->frame.argc); - MEMCPY(data->frame.argv, orig->frame.argv, VALUE, orig->frame.argc); + frame_dup(&data->frame); @@ -5391,2 +5427,3 @@ data->iter = rb_f_iterator_p(); + frame_dup(&data->frame); if (ruby_frame->prev) { @@ -5394,4 +5431,2 @@ } - data->frame.argv = ALLOC_N(VALUE, data->frame.argc); - MEMCPY(data->frame.argv, ruby_block->frame.argv, VALUE, data->frame.argc); @@ -5469,4 +5504,3 @@ data->iter = data->prev?Qtrue:Qfalse; - data->frame.argv = ALLOC_N(VALUE, data->frame.argc); - MEMCPY(data->frame.argv, ruby_block->frame.argv, VALUE, data->frame.argc); + frame_dup(&data->frame); if (data->iter) {