summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-compiler/core/codegen.c
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems/mruby-compiler/core/codegen.c')
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c
index bd3f34ddd..fce55999d 100644
--- a/mrbgems/mruby-compiler/core/codegen.c
+++ b/mrbgems/mruby-compiler/core/codegen.c
@@ -494,6 +494,22 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep)
}
}
+static int search_upvar(codegen_scope *s, mrb_sym id, int *idx);
+
+static void
+gen_getupvar(codegen_scope *s, uint16_t dst, mrb_sym id)
+{
+ int idx;
+ int lv = search_upvar(s, id, &idx);
+
+ struct mrb_insn_data data = mrb_last_insn(s);
+ if (!no_peephole(s) && data.insn == OP_SETUPVAR && data.a == dst && data.b == idx && data.c == lv) {
+ /* skip GETUPVAR right after SETUPVAR */
+ return;
+ }
+ genop_3(s, OP_GETUPVAR, dst, idx, lv);
+}
+
static void
gen_return(codegen_scope *s, uint8_t op, uint16_t src)
{
@@ -966,8 +982,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
gen_move(s, idx, cursp(), 0);
}
else {
- int lv = search_upvar(s, id, &idx);
- genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
+ gen_getupvar(s, cursp(), id);
}
i++;
opt = opt->cdr;
@@ -1005,8 +1020,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
gen_move(s, idx, cursp(), 0);
}
else {
- int lv = search_upvar(s, kwd_sym, &idx);
- genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
+ gen_getupvar(s, cursp(), kwd_sym);
}
jmp_def_set = genjmp_0(s, OP_JMP);
dispatch(s, jmpif_key_p);
@@ -2461,8 +2475,7 @@ codegen(codegen_scope *s, node *tree, int val)
gen_move(s, cursp(), idx, val);
}
else {
- int lv = search_upvar(s, nsym(tree), &idx);
- genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
+ gen_getupvar(s, cursp(), nsym(tree));
}
push();
}