summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-eval/src/eval.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-05-15 21:02:53 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-05-15 21:02:53 +0900
commit60051de4019b8aab435f6568b960bdeaff4be815 (patch)
tree60e3d882ffbeca0e191257e15446d1aaa8a6412d /mrbgems/mruby-eval/src/eval.c
parent9dae3f67d63d1d9ed86e1cbb815365cfb4023b90 (diff)
parentda8d07d5d42b5a56fea8d30df816b7ee7c7da382 (diff)
downloadmruby-60051de4019b8aab435f6568b960bdeaff4be815.tar.gz
mruby-60051de4019b8aab435f6568b960bdeaff4be815.zip
Merge pull request #2257 from miura1729/original2
Suport block in Kernel#eval
Diffstat (limited to 'mrbgems/mruby-eval/src/eval.c')
-rw-r--r--mrbgems/mruby-eval/src/eval.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
index 8969722f7..78c47750b 100644
--- a/mrbgems/mruby-eval/src/eval.c
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -26,7 +26,7 @@ get_closure_irep(mrb_state *mrb, int level)
}
static inline mrb_code
-search_variable(mrb_state *mrb, mrb_sym vsym)
+search_variable(mrb_state *mrb, mrb_sym vsym, int bnest)
{
mrb_irep *virep;
int level;
@@ -38,7 +38,7 @@ search_variable(mrb_state *mrb, mrb_sym vsym)
}
for (pos = 0; pos < virep->nlocals - 1; pos++) {
if (vsym == virep->lv[pos].name) {
- return (MKARG_B(pos + 1) | MKARG_C(level));
+ return (MKARG_B(pos + 1) | MKARG_C(level + bnest));
}
}
}
@@ -48,11 +48,15 @@ search_variable(mrb_state *mrb, mrb_sym vsym)
static void
-patch_irep(mrb_state *mrb, mrb_irep *irep)
+patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest)
{
size_t i;
mrb_code c;
+ for (i = 0; i < irep->rlen; i++) {
+ patch_irep(mrb, irep->reps[i], bnest + 1);
+ }
+
for (i = 0; i < irep->ilen; i++) {
c = irep->iseq[i];
switch(GET_OPCODE(c)){
@@ -61,7 +65,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep)
break;
}
{
- mrb_code arg = search_variable(mrb, irep->syms[GETARG_B(c)]);
+ mrb_code arg = search_variable(mrb, irep->syms[GETARG_B(c)], bnest);
if (arg != 0) {
/* must replace */
irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
@@ -72,7 +76,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep)
case OP_MOVE:
/* src part */
if (GETARG_B(c) < irep->nlocals) {
- mrb_code arg = search_variable(mrb, irep->lv[GETARG_B(c) - 1].name);
+ mrb_code arg = search_variable(mrb, irep->lv[GETARG_B(c) - 1].name, bnest);
if (arg != 0) {
/* must replace */
irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
@@ -80,7 +84,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep)
}
/* dst part */
if (GETARG_A(c) < irep->nlocals) {
- mrb_code arg = search_variable(mrb, irep->lv[GETARG_A(c) - 1].name);
+ mrb_code arg = search_variable(mrb, irep->lv[GETARG_A(c) - 1].name, bnest);
if (arg != 0) {
/* must replace */
irep->iseq[i] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_B(c)) | arg;
@@ -131,7 +135,7 @@ create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, cha
e->stack = mrb->c->ci->stackent;
mrb->c->ci->env = e;
proc->env = e;
- patch_irep(mrb, proc->body.irep);
+ patch_irep(mrb, proc->body.irep, 0);
mrb_parser_free(p);
mrbc_context_free(mrb, cxt);