diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-05-15 21:02:53 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-05-15 21:02:53 +0900 |
| commit | 60051de4019b8aab435f6568b960bdeaff4be815 (patch) | |
| tree | 60e3d882ffbeca0e191257e15446d1aaa8a6412d | |
| parent | 9dae3f67d63d1d9ed86e1cbb815365cfb4023b90 (diff) | |
| parent | da8d07d5d42b5a56fea8d30df816b7ee7c7da382 (diff) | |
| download | mruby-60051de4019b8aab435f6568b960bdeaff4be815.tar.gz mruby-60051de4019b8aab435f6568b960bdeaff4be815.zip | |
Merge pull request #2257 from miura1729/original2
Suport block in Kernel#eval
| -rw-r--r-- | mrbgems/mruby-eval/src/eval.c | 18 | ||||
| -rw-r--r-- | mrbgems/mruby-eval/test/eval.rb | 14 |
2 files changed, 25 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); diff --git a/mrbgems/mruby-eval/test/eval.rb b/mrbgems/mruby-eval/test/eval.rb index 29cd3a491..115e6e358 100644 --- a/mrbgems/mruby-eval/test/eval.rb +++ b/mrbgems/mruby-eval/test/eval.rb @@ -18,6 +18,20 @@ assert('Kernel.eval') do }.call c } + assert_equal(5) { + c = 5 + lambda { + Kernel.eval 'lambda { c }.call' + }.call + } + assert_equal(15) { + c = 5 + lambda { + a = 10 + Kernel.eval 'lambda { c = a + c }.call' + }.call + c + } end assert('eval') do |
