diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-09-10 10:23:28 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-09-10 10:23:28 +0900 |
| commit | 28b5c30b964c9e6121a2ee04454905c81a3e2646 (patch) | |
| tree | 8e63ca79d1404d32534dcb2a0022c064d6bfabc6 | |
| parent | b34713304a983a0a6e3259bd0b5f3215ac2ee14a (diff) | |
| download | mruby-28b5c30b964c9e6121a2ee04454905c81a3e2646.tar.gz mruby-28b5c30b964c9e6121a2ee04454905c81a3e2646.zip | |
ops.h: add `OP_SYMBOL` instruction.
It generates a symbol by interning from the pool string.
| -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; } |
