1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46648 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2014-07-01 17:57:37 +00:00
parent 0fdb18e513
commit 1a2b90d5e6
6 changed files with 44 additions and 36 deletions

View file

@ -1,3 +1,10 @@
Wed Jul 2 02:57:27 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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@ruby-lang.org>
* proc.c (bind_receiver): new method to return the bound receiver

28
proc.c
View file

@ -467,36 +467,10 @@ check_local_id(VALUE bindval, volatile VALUE *pname)
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);
}
/*

View file

@ -1253,7 +1253,9 @@ class TestProc < Test::Unit::TestCase
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

12
vm.c
View file

@ -566,6 +566,18 @@ vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *ep, const struc
}
}
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);

View file

@ -856,6 +856,7 @@ VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
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);

View file

@ -1876,6 +1876,24 @@ rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, int *stateptr)
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
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)
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);
}
/*