aboutsummaryrefslogtreecommitdiffstats
path: root/vm.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-09 09:51:00 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-09 09:51:00 +0000
commit568c5a8193006d12a47befaf493d1bbd76a5a5cd (patch)
treed70c1fb440341f3942b63f5a2254ea0fbe387996 /vm.c
parenta62d6e64bf1da39f529396fd06a9dd1f1526c90f (diff)
downloadruby-568c5a8193006d12a47befaf493d1bbd76a5a5cd.tar.gz
* 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
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c38
1 files changed, 38 insertions, 0 deletions
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