ruby-changes:51288
From: ko1 <ko1@a...>
Date: Wed, 23 May 2018 15:56:13 +0900 (JST)
Subject: [ruby-changes:51288] ko1:r63494 (trunk): remove VM_ENV_DATA_INDEX_ENV_PROC.
ko1 2018-05-23 15:56:08 +0900 (Wed, 23 May 2018) New Revision: 63494 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=63494 Log: 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] Modified files: trunk/proc.c trunk/test/ruby/test_proc.rb trunk/vm.c trunk/vm_core.h Index: vm_core.h =================================================================== --- vm_core.h (revision 63493) +++ vm_core.h (revision 63494) @@ -1084,7 +1084,6 @@ enum { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1084 #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) https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1222 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) { Index: proc.c =================================================================== --- proc.c (revision 63493) +++ proc.c (revision 63494) @@ -706,13 +706,6 @@ proc_new(VALUE klass, int8_t is_lambda) https://github.com/ruby/ruby/blob/trunk/proc.c#L706 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) https://github.com/ruby/ruby/blob/trunk/proc.c#L723 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; Index: vm.c =================================================================== --- vm.c (revision 63493) +++ vm.c (revision 63494) @@ -634,28 +634,25 @@ check_env_value(const rb_env_t *env) https://github.com/ruby/ruby/blob/trunk/vm.c#L634 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_cont https://github.com/ruby/ruby/blob/trunk/vm.c#L682 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_cont https://github.com/ruby/ruby/blob/trunk/vm.c#L707 */ 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_cont https://github.com/ruby/ruby/blob/trunk/vm.c#L725 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 */ Index: test/ruby/test_proc.rb =================================================================== --- test/ruby/test_proc.rb (revision 63493) +++ test/ruby/test_proc.rb (revision 63494) @@ -1408,4 +1408,12 @@ class TestProc < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_proc.rb#L1408 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/