diff options
| -rw-r--r-- | include/mruby/ops.h | 1 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 10 | ||||
| -rw-r--r-- | src/codedump.c | 5 | ||||
| -rw-r--r-- | src/vm.c | 17 |
4 files changed, 32 insertions, 1 deletions
diff --git a/include/mruby/ops.h b/include/mruby/ops.h index fae6872cc..705247649 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -91,6 +91,7 @@ OPCODE(AREF, BBB) /* R(a) = R(b)[c] */ OPCODE(ASET, BBB) /* R(a)[c] = R(b) */ OPCODE(APOST, BBB) /* *R(a),R(a+1)..R(a+c) = R(a)[b..] */ OPCODE(INTERN, B) /* R(a) = intern(R(a)) */ +OPCODE(SYMBOL, BB) /* R(a) = intern(Pool(b)) */ OPCODE(STRING, BB) /* R(a) = str_dup(Pool(b)) */ OPCODE(STRCAT, B) /* str_cat(R(a),R(a+1)) */ OPCODE(HASH, BB) /* R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1)) */ diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index b8891cf1b..7327f2cef 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -1757,6 +1757,16 @@ static void gen_intern(codegen_scope *s) { pop(); + if (!no_peephole(s)) { + struct mrb_insn_data data = mrb_last_insn(s); + + if (data.insn == OP_STRING && data.a == cursp()) { + rewind_pc(s); + genop_2(s, OP_SYMBOL, data.a, data.b); + push(); + return; + } + } genop_1(s, OP_INTERN, cursp()); push(); } diff --git a/src/codedump.c b/src/codedump.c index 542e54904..b0a7676f0 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -455,6 +455,11 @@ codedump(mrb_state *mrb, const mrb_irep *irep) printf("OP_INTERN\tR%d", a); print_lv_a(mrb, irep, a); break; + CASE(OP_SYMBOL, BB): + mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0); + printf("OP_SYMBOL\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); + print_lv_a(mrb, irep, a); + break; CASE(OP_STRING, BB): if ((irep->pool[b].tt & IREP_TT_NFLAG) == 0) { printf("OP_STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); @@ -2630,7 +2630,22 @@ RETRY_TRY_BLOCK: mrb_sym sym = mrb_intern_str(mrb, regs[a]); regs[a] = mrb_symbol_value(sym); - mrb_gc_arena_restore(mrb, ai); + NEXT; + } + + CASE(OP_SYMBOL, BB) { + size_t len; + mrb_sym sym; + + mrb_assert((pool[b].tt&IREP_TT_NFLAG)==0); + len = pool[b].tt >> 2; + if (pool[b].tt & IREP_TT_SFLAG) { + sym = mrb_intern_static(mrb, pool[b].u.str, len); + } + else { + sym = mrb_intern(mrb, pool[b].u.str, len); + } + regs[a] = mrb_symbol_value(sym); NEXT; } |
