ruby-changes:34567
From: nobu <ko1@a...>
Date: Wed, 2 Jul 2014 02:57:41 +0900 (JST)
Subject: [ruby-changes:34567] nobu:r46648 (trunk): vm.c: rb_vm_env_local_variables
nobu 2014-07-02 02:57:37 +0900 (Wed, 02 Jul 2014) New Revision: 46648 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46648 Log: vm.c: rb_vm_env_local_variables * vm.c (rb_vm_env_local_variables): returns array of local variable name symbols in the environment by envval. * proc.c (bind_local_variables): use rb_vm_env_local_variables. Modified files: trunk/ChangeLog trunk/proc.c trunk/test/ruby/test_proc.rb trunk/vm.c trunk/vm_core.h trunk/vm_eval.c Index: ChangeLog =================================================================== --- ChangeLog (revision 46647) +++ ChangeLog (revision 46648) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Jul 2 02:57:27 2014 Nobuyoshi Nakada <nobu@r...> + + * vm.c (rb_vm_env_local_variables): returns array of local + variable name symbols in the environment by envval. + + * proc.c (bind_local_variables): use rb_vm_env_local_variables. + Wed Jul 2 02:23:52 2014 Nobuyoshi Nakada <nobu@r...> * proc.c (bind_receiver): new method to return the bound receiver Index: vm_core.h =================================================================== --- vm_core.h (revision 46647) +++ vm_core.h (revision 46648) @@ -856,6 +856,7 @@ VALUE rb_vm_invoke_proc(rb_thread_t *th, https://github.com/ruby/ruby/blob/trunk/vm_core.h#L856 int argc, const VALUE *argv, const rb_block_t *blockptr); VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass); VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp); +VALUE rb_vm_env_local_variables(VALUE envval); VALUE rb_binding_new_with_cfp(rb_thread_t *th, const rb_control_frame_t *src_cfp); VALUE *rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars); void rb_vm_inc_const_missing_count(void); Index: vm_eval.c =================================================================== --- vm_eval.c (revision 46647) +++ vm_eval.c (revision 46648) @@ -1876,6 +1876,24 @@ rb_catch_protect(VALUE t, rb_block_call_ https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1876 return val; } +static void +local_var_list_init(struct local_var_list *vars) +{ + vars->tbl = rb_hash_new(); + RHASH(vars->tbl)->ntbl = st_init_numtable(); /* compare_by_identity */ + RBASIC_CLEAR_CLASS(vars->tbl); +} + +static VALUE +local_var_list_finish(struct local_var_list *vars) +{ + /* TODO: not to depend on the order of st_table */ + VALUE ary = rb_hash_keys(vars->tbl); + rb_hash_clear(vars->tbl); + vars->tbl = 0; + return ary; +} + static int local_var_list_update(st_data_t *key, st_data_t *value, st_data_t arg, int existing) { @@ -1912,15 +1930,12 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1930 rb_f_local_variables(void) { struct local_var_list vars; - VALUE ary; rb_thread_t *th = GET_THREAD(); rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp)); int i; - vars.tbl = rb_hash_new(); - RHASH(vars.tbl)->ntbl = st_init_numtable(); /* compare_by_identity */ - RBASIC_CLEAR_CLASS(vars.tbl); + local_var_list_init(&vars); while (cfp) { if (cfp->iseq) { for (i = 0; i < cfp->iseq->local_table_size; i++) { @@ -1944,10 +1959,7 @@ rb_f_local_variables(void) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1959 break; } } - /* TODO: not to depend on the order of st_table */ - ary = rb_hash_keys(vars.tbl); - rb_hash_clear(vars.tbl); - return ary; + return local_var_list_finish(&vars); } /* Index: proc.c =================================================================== --- proc.c (revision 46647) +++ proc.c (revision 46648) @@ -467,36 +467,10 @@ check_local_id(VALUE bindval, volatile V https://github.com/ruby/ruby/blob/trunk/proc.c#L467 static VALUE bind_local_variables(VALUE bindval) { - VALUE ary = rb_ary_new(); - const rb_binding_t *bind; - const rb_env_t *env; - VALUE envval; GetBindingPtr(bindval, bind); - - envval = bind->env; - - do { - const rb_iseq_t *iseq; - int i; - ID id; - - GetEnvPtr(envval, env); - iseq = env->block.iseq; - - for (i = 0; i < iseq->local_table_size; i++) { - id = iseq->local_table[i]; - if (id) { - const char *vname = rb_id2name(id); - if (vname) { - rb_ary_push(ary, ID2SYM(id)); - } - } - } - } while ((envval = env->prev_envval) != 0); - - return ary; + return rb_vm_env_local_variables(bind->env); } /* Index: vm.c =================================================================== --- vm.c (revision 46647) +++ vm.c (revision 46648) @@ -566,6 +566,18 @@ vm_collect_local_variables_in_heap(rb_th https://github.com/ruby/ruby/blob/trunk/vm.c#L566 } } +VALUE +rb_vm_env_local_variables(VALUE envval) +{ + struct local_var_list vars; + const rb_env_t *env; + + GetEnvPtr(envval, env); + local_var_list_init(&vars); + collect_local_variables_in_env(env, &vars); + return local_var_list_finish(&vars); +} + static void vm_rewrite_ep_in_errinfo(rb_thread_t *th); static VALUE vm_make_proc_from_block(rb_thread_t *th, rb_block_t *block); static VALUE vm_make_env_object(rb_thread_t * th, rb_control_frame_t *cfp, VALUE *blockprocptr); Index: test/ruby/test_proc.rb =================================================================== --- test/ruby/test_proc.rb (revision 46647) +++ test/ruby/test_proc.rb (revision 46648) @@ -1253,7 +1253,9 @@ class TestProc < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_proc.rb#L1253 def test_local_variables b = get_binding - assert_equal(%i[if case when begin end a], b.local_variables) + assert_equal(%i'if case when begin end a', b.local_variables) + a = tap {|;a, b| break binding.local_variables} + assert_equal(%i[a b], a.sort) end def test_local_variables_nested -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/