mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	remove VM_ENV_DATA_INDEX_ENV_PROC.
* vm_core.h (VM_ENV_DATA_INDEX_ENV_PROC): ep[VM_ENV_DATA_INDEX_ENV_PROC] is allocated to mark a Proc which is created from iseq block. However, `lep[0]` keeps Proc object itself as a block handler (Proc). So we don't need to keep it. * vm_core.h (VM_ENV_PROCVAL): ditto. * vm.c (vm_make_env_each): do not need to keep blockprocval as special value. * vm.c (vm_block_handler_escape): simply return Proc value. * proc.c (proc_new): we don't need to check Env because a Proc type block handler is a Proc object itself. [Bug #14782] * test/ruby/test_proc.rb: add a test for [Bug #14782] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63494 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									b32b2a6106
								
							
						
					
					
						commit
						e6ad53beaa
					
				
					 4 changed files with 16 additions and 32 deletions
				
			
		
							
								
								
									
										10
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								proc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -706,13 +706,6 @@ proc_new(VALUE klass, int8_t is_lambda)
 | 
			
		|||
	cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
 | 
			
		||||
 | 
			
		||||
	if ((block_handler = rb_vm_frame_block_handler(cfp)) != VM_BLOCK_HANDLER_NONE) {
 | 
			
		||||
	    const VALUE *lep = rb_vm_ep_local_ep(cfp->ep);
 | 
			
		||||
 | 
			
		||||
	    if (VM_ENV_ESCAPED_P(lep)) {
 | 
			
		||||
		procval = VM_ENV_PROCVAL(lep);
 | 
			
		||||
		goto return_existing_proc;
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
	    if (is_lambda) {
 | 
			
		||||
		rb_warn(proc_without_block);
 | 
			
		||||
	    }
 | 
			
		||||
| 
						 | 
				
			
			@ -730,13 +723,12 @@ proc_new(VALUE klass, int8_t is_lambda)
 | 
			
		|||
      case block_handler_type_proc:
 | 
			
		||||
	procval = VM_BH_TO_PROC(block_handler);
 | 
			
		||||
 | 
			
		||||
      return_existing_proc:
 | 
			
		||||
	if (RBASIC_CLASS(procval) == klass) {
 | 
			
		||||
	    return procval;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
	    VALUE newprocval = rb_proc_dup(procval);
 | 
			
		||||
	    RBASIC_SET_CLASS(newprocval, klass);
 | 
			
		||||
            RBASIC_SET_CLASS(newprocval, klass);
 | 
			
		||||
	    return newprocval;
 | 
			
		||||
	}
 | 
			
		||||
	break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1408,4 +1408,12 @@ class TestProc < Test::Unit::TestCase
 | 
			
		|||
      m {}
 | 
			
		||||
    end;
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def method_for_test_proc_without_block_for_symbol
 | 
			
		||||
    binding.eval('proc')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_proc_without_block_for_symbol
 | 
			
		||||
    assert_equal('1', method_for_test_proc_without_block_for_symbol(&:to_s).call(1), '[Bug #14782]')
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										19
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								vm.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -634,28 +634,25 @@ check_env_value(const rb_env_t *env)
 | 
			
		|||
    return Qnil;		/* unreachable */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
vm_block_handler_escape(const rb_execution_context_t *ec, VALUE block_handler, VALUE *procvalptr)
 | 
			
		||||
static VALUE
 | 
			
		||||
vm_block_handler_escape(const rb_execution_context_t *ec, VALUE block_handler)
 | 
			
		||||
{
 | 
			
		||||
    switch (vm_block_handler_type(block_handler)) {
 | 
			
		||||
      case block_handler_type_ifunc:
 | 
			
		||||
      case block_handler_type_iseq:
 | 
			
		||||
	*procvalptr = rb_vm_make_proc(ec, VM_BH_TO_CAPT_BLOCK(block_handler), rb_cProc);
 | 
			
		||||
	return;
 | 
			
		||||
        return  rb_vm_make_proc(ec, VM_BH_TO_CAPT_BLOCK(block_handler), rb_cProc);
 | 
			
		||||
 | 
			
		||||
      case block_handler_type_symbol:
 | 
			
		||||
      case block_handler_type_proc:
 | 
			
		||||
	*procvalptr = block_handler;
 | 
			
		||||
	return;
 | 
			
		||||
        return block_handler;
 | 
			
		||||
    }
 | 
			
		||||
    VM_UNREACHABLE(vm_block_handler_escape);
 | 
			
		||||
    return;
 | 
			
		||||
    return Qnil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
vm_make_env_each(const rb_execution_context_t * const ec, rb_control_frame_t *const cfp)
 | 
			
		||||
{
 | 
			
		||||
    VALUE blockprocval = Qfalse;
 | 
			
		||||
    const VALUE * const ep = cfp->ep;
 | 
			
		||||
    const rb_env_t *env;
 | 
			
		||||
    const rb_iseq_t *env_iseq;
 | 
			
		||||
| 
						 | 
				
			
			@ -685,7 +682,7 @@ vm_make_env_each(const rb_execution_context_t * const ec, rb_control_frame_t *co
 | 
			
		|||
	VALUE block_handler = VM_ENV_BLOCK_HANDLER(ep);
 | 
			
		||||
 | 
			
		||||
	if (block_handler != VM_BLOCK_HANDLER_NONE) {
 | 
			
		||||
	    vm_block_handler_escape(ec, block_handler, &blockprocval);
 | 
			
		||||
            VALUE blockprocval = vm_block_handler_escape(ec, block_handler);
 | 
			
		||||
	    VM_STACK_ENV_WRITE(ep, VM_ENV_DATA_INDEX_SPECVAL, blockprocval);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -710,8 +707,7 @@ vm_make_env_each(const rb_execution_context_t * const ec, rb_control_frame_t *co
 | 
			
		|||
     */
 | 
			
		||||
 | 
			
		||||
    env_size = local_size +
 | 
			
		||||
	       1 /* envval */ +
 | 
			
		||||
	       (blockprocval ? 1 : 0) /* blockprocval */;
 | 
			
		||||
	       1 /* envval */;
 | 
			
		||||
    env_body = ALLOC_N(VALUE, env_size);
 | 
			
		||||
    MEMCPY(env_body, ep - (local_size - 1 /* specval */), VALUE, local_size);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -729,7 +725,6 @@ vm_make_env_each(const rb_execution_context_t * const ec, rb_control_frame_t *co
 | 
			
		|||
 | 
			
		||||
    env = vm_env_new(env_ep, env_body, env_size, env_iseq);
 | 
			
		||||
 | 
			
		||||
    if (blockprocval) RB_OBJ_WRITE(env, &env_ep[2], blockprocval);
 | 
			
		||||
    cfp->ep = env_ep;
 | 
			
		||||
    VM_ENV_FLAGS_SET(env_ep, VM_ENV_FLAG_ESCAPED | VM_ENV_FLAG_WB_REQUIRED);
 | 
			
		||||
    VM_STACK_ENV_WRITE(ep, 0, (VALUE)env);		/* GC mark */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								vm_core.h
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								vm_core.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1084,7 +1084,6 @@ enum {
 | 
			
		|||
#define VM_ENV_DATA_INDEX_SPECVAL    (-1) /* ep[-1] */
 | 
			
		||||
#define VM_ENV_DATA_INDEX_FLAGS      ( 0) /* ep[ 0] */
 | 
			
		||||
#define VM_ENV_DATA_INDEX_ENV        ( 1) /* ep[ 1] */
 | 
			
		||||
#define VM_ENV_DATA_INDEX_ENV_PROC   ( 2) /* ep[ 2] */
 | 
			
		||||
 | 
			
		||||
#define VM_ENV_INDEX_LAST_LVAR              (-VM_ENV_DATA_SIZE)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1223,16 +1222,6 @@ VM_ENV_ENVVAL_PTR(const VALUE *ep)
 | 
			
		|||
    return (const rb_env_t *)VM_ENV_ENVVAL(ep);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline VALUE
 | 
			
		||||
VM_ENV_PROCVAL(const VALUE *ep)
 | 
			
		||||
{
 | 
			
		||||
    VM_ASSERT(VM_ENV_ESCAPED_P(ep));
 | 
			
		||||
    VM_ASSERT(VM_ENV_LOCAL_P(ep));
 | 
			
		||||
    VM_ASSERT(VM_ENV_BLOCK_HANDLER(ep) != VM_BLOCK_HANDLER_NONE);
 | 
			
		||||
 | 
			
		||||
    return ep[VM_ENV_DATA_INDEX_ENV_PROC];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline const rb_env_t *
 | 
			
		||||
vm_env_new(VALUE *env_ep, VALUE *env_body, unsigned int env_size, const rb_iseq_t *iseq)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue