Commit 60051de4 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #2257 from miura1729/original2

Suport block in Kernel#eval
parents 9dae3f67 da8d07d5
...@@ -26,7 +26,7 @@ get_closure_irep(mrb_state *mrb, int level) ...@@ -26,7 +26,7 @@ get_closure_irep(mrb_state *mrb, int level)
} }
static inline mrb_code 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; mrb_irep *virep;
int level; int level;
...@@ -38,7 +38,7 @@ search_variable(mrb_state *mrb, mrb_sym vsym) ...@@ -38,7 +38,7 @@ search_variable(mrb_state *mrb, mrb_sym vsym)
} }
for (pos = 0; pos < virep->nlocals - 1; pos++) { for (pos = 0; pos < virep->nlocals - 1; pos++) {
if (vsym == virep->lv[pos].name) { 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) ...@@ -48,11 +48,15 @@ search_variable(mrb_state *mrb, mrb_sym vsym)
static void static void
patch_irep(mrb_state *mrb, mrb_irep *irep) patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest)
{ {
size_t i; size_t i;
mrb_code c; 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++) { for (i = 0; i < irep->ilen; i++) {
c = irep->iseq[i]; c = irep->iseq[i];
switch(GET_OPCODE(c)){ switch(GET_OPCODE(c)){
...@@ -61,7 +65,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep) ...@@ -61,7 +65,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep)
break; 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) { if (arg != 0) {
/* must replace */ /* must replace */
irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg; irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
...@@ -72,7 +76,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep) ...@@ -72,7 +76,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep)
case OP_MOVE: case OP_MOVE:
/* src part */ /* src part */
if (GETARG_B(c) < irep->nlocals) { 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) { if (arg != 0) {
/* must replace */ /* must replace */
irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg; irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
...@@ -80,7 +84,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep) ...@@ -80,7 +84,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep)
} }
/* dst part */ /* dst part */
if (GETARG_A(c) < irep->nlocals) { 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) { if (arg != 0) {
/* must replace */ /* must replace */
irep->iseq[i] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_B(c)) | arg; 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 ...@@ -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; e->stack = mrb->c->ci->stackent;
mrb->c->ci->env = e; mrb->c->ci->env = e;
proc->env = e; proc->env = e;
patch_irep(mrb, proc->body.irep); patch_irep(mrb, proc->body.irep, 0);
mrb_parser_free(p); mrb_parser_free(p);
mrbc_context_free(mrb, cxt); mrbc_context_free(mrb, cxt);
......
...@@ -18,6 +18,20 @@ assert('Kernel.eval') do ...@@ -18,6 +18,20 @@ assert('Kernel.eval') do
}.call }.call
c 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 end
assert('eval') do assert('eval') do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment