[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]