(2012/08/22 11:46), shugo (Shugo Maeda) wrote:
> とりあえず、現在のフレームにVM_FRAME_FLAG_FINISHフラグが立っていたら
> VM_CALL_TAILCALL_BITが立っている時でもpopしないようにしたところ、
> SEGVが発生しなくなりましたが、問題ないでしょうか? > ささださん

 SEGV しなくなる点で問題ないかと思いますが,意図はしたものではないよう
な気がします.

 下記のような感じでどうでしょうか.さっきコミットされていたテストが
SEGV しなくなりました.

http://www.atdot.net/sp/raw/9r559m

> Index: vm_insnhelper.c
> ===================================================================
> --- vm_insnhelper.c	(revision 36772)
> +++ vm_insnhelper.c	(working copy)
> @@ -510,8 +510,7 @@ vm_setup_method(rb_thread_t *th, rb_cont
>  
>      sp = rsp + iseq->arg_size;
>  
> -    if (LIKELY(!(flag & VM_CALL_TAILCALL_BIT) ||
> -	       VM_FRAME_TYPE_FINISH_P(th->cfp))) {
> +    if (LIKELY(!(flag & VM_CALL_TAILCALL_BIT))) {
>  	if (0) printf("local_size: %d, arg_size: %d\n",
>  		      iseq->local_size, iseq->arg_size);
>  
> @@ -528,6 +527,8 @@ vm_setup_method(rb_thread_t *th, rb_cont
>      }
>      else {
>  	VALUE *p_rsp;
> +	int is_finish_frame = VM_FRAME_TYPE_FINISH_P(cfp);
> +
>  	th->cfp++; /* pop cf */
>  	p_rsp = th->cfp->sp;
>  
> @@ -543,8 +544,8 @@ vm_setup_method(rb_thread_t *th, rb_cont
>  	    *sp++ = Qnil;
>  	}
>  
> -	vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, recv, defined_class,
> -		      VM_ENVVAL_BLOCK_PTR(blockptr),
> +	vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD | (is_finish_frame ? VM_FRAME_FLAG_FINISH : 0),
> +		      recv, defined_class, VM_ENVVAL_BLOCK_PTR(blockptr),
>  		      iseq->iseq_encoded + opt_pc, sp, 0, me);
>      }
>  }

-- 
// SASADA Koichi at atdot dot net