From 568c5a8193006d12a47befaf493d1bbd76a5a5cd Mon Sep 17 00:00:00 2001 From: ko1 Date: Fri, 9 Aug 2013 09:51:00 +0000 Subject: * proc.c: add Binding#local_variable_get/set/defined? to access local variables which a binding contains. Most part of implementation by nobu. * test/ruby/test_proc.rb: add a tests for above. * vm.c, vm_core.h (rb_binding_add_dynavars): add a new function to add a new environment to create space for new local variables. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42464 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- vm.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'vm.c') diff --git a/vm.c b/vm.c index a8246d4c24..8dd71e2b3d 100644 --- a/vm.c +++ b/vm.c @@ -602,6 +602,44 @@ rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass) return procval; } +VALUE * +rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars) +{ + VALUE envval = bind->env, path = bind->path, iseqval; + rb_env_t *env; + rb_block_t *base_block; + rb_thread_t *th = GET_THREAD(); + rb_iseq_t *base_iseq; + NODE *node = 0; + ID minibuf[4], *dyns = minibuf; + VALUE idtmp = 0; + + if (dyncount < 0) return 0; + + GetEnvPtr(envval, env); + + base_block = &env->block; + base_iseq = base_block->iseq; + + if (dyncount >= numberof(minibuf)) dyns = ALLOCV_N(ID, idtmp, dyncount + 1); + + dyns[0] = dyncount; + MEMCPY(dyns + 1, dynvars, ID, dyncount); + node = NEW_NODE(NODE_SCOPE, dyns, 0, 0); + + iseqval = rb_iseq_new(node, base_iseq->location.label, path, path, + base_iseq->self, ISEQ_TYPE_EVAL); + node->u1.tbl = 0; /* reset table */ + ALLOCV_END(idtmp); + + vm_set_eval_stack(th, iseqval, 0, base_block); + bind->env = rb_vm_make_env_object(th, th->cfp); + vm_pop_frame(th); + GetEnvPtr(bind->env, env); + + return env->env; +} + /* C -> Ruby: block */ static inline VALUE -- cgit v1.2.3