ops.h: add `OP_SYMBOL` instruction.
It generates a symbol by interning from the pool string.
MODIFY
include/mruby/ops.h
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)) */

MODIFY
mrbgems/mruby-compiler/core/codegen.c
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();
}

MODIFY
src/codedump.c
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);

MODIFY
src/vm.c
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;
}

ops.h: add `OP_SYMBOL` instruction.

It generates a symbol by interning from the pool string.