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:
parent
0fdb18e513
commit
1a2b90d5e6
6 changed files with 44 additions and 36 deletions
|
@ -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
28
proc.c
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
12
vm.c
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
28
vm_eval.c
28
vm_eval.c
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Reference in a new issue