ops.h: add `OP_SYMBOL` instruction.

It generates a symbol by interning from the pool string.
parent b3471330
......@@ -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)) */
......
......@@ -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();
}
......
......@@ -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;
}
......
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