summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/ops.h1
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c10
-rw-r--r--src/codedump.c5
-rw-r--r--src/vm.c17
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);
diff --git a/src/vm.c b/src/vm.c
index 1cc3a8df7..8ed22d7f6 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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;
}