diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-01-19 00:13:44 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-01-19 00:13:44 +0000 |
commit | 4316e4d99b856fcd16a2aa0f08cb6285dcab24af (patch) | |
tree | dd506ad60e9256c9e9046867e6108a60fe84c3c3 /vm_eval.c | |
parent | b96f428e4892e4eb568ae47478947b886ae2dc87 (diff) | |
download | bundler-4316e4d99b856fcd16a2aa0f08cb6285dcab24af.tar.gz |
* eval.c, vm_eval.c (rb_f_local_variables): move definition from eval.c
to vm_eval.c because vm_collect_local_variables_in_heap() should
be static function.
* vm.c (vm_collect_local_variables_in_heap): make it static.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_eval.c')
-rw-r--r-- | vm_eval.c | 58 |
1 files changed, 58 insertions, 0 deletions
@@ -19,6 +19,7 @@ static inline VALUE vm_backtrace(rb_thread_t *th, int lev); static NODE *vm_cref_push(rb_thread_t *th, VALUE klass, int noex); static VALUE vm_exec(rb_thread_t *th); static void vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref); +static int vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary); static inline VALUE vm_call0(rb_thread_t * th, VALUE klass, VALUE recv, VALUE id, ID oid, @@ -1322,10 +1323,67 @@ rb_make_backtrace(void) return vm_backtrace(GET_THREAD(), -1); } +/* + * call-seq: + * local_variables => array + * + * Returns the names of the current local variables. + * + * fred = 1 + * for i in 1..10 + * # ... + * end + * local_variables #=> ["fred", "i"] + */ + +static VALUE +rb_f_local_variables(void) +{ + VALUE ary = rb_ary_new(); + 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; + + while (cfp) { + if (cfp->iseq) { + for (i = 0; i < cfp->iseq->local_table_size; i++) { + ID lid = cfp->iseq->local_table[i]; + if (lid) { + const char *vname = rb_id2name(lid); + /* should skip temporary variable */ + if (vname) { + rb_ary_push(ary, ID2SYM(lid)); + } + } + } + } + if (cfp->lfp != cfp->dfp) { + /* block */ + VALUE *dfp = GC_GUARDED_PTR_REF(cfp->dfp[0]); + + if (vm_collect_local_variables_in_heap(th, dfp, ary)) { + break; + } + else { + while (cfp->dfp != dfp) { + cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); + } + } + } + else { + break; + } + } + return ary; +} + void Init_vm_eval(void) { rb_define_global_function("eval", rb_f_eval, -1); + rb_define_global_function("local_variables", rb_f_local_variables, 0); + rb_define_global_function("catch", rb_f_catch, -1); rb_define_global_function("throw", rb_f_throw, -1); |