diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-05-24 15:19:06 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-08-25 09:41:21 +0900 |
| commit | eeb6d5658d9e29ad24f211a3236eb02abcdb136c (patch) | |
| tree | a8f7c8138a668857303f435c569d517b1c2e47fc | |
| parent | a16885efe5125944316b48c644c3a9eae2fc568e (diff) | |
| download | mruby-eeb6d5658d9e29ad24f211a3236eb02abcdb136c.tar.gz mruby-eeb6d5658d9e29ad24f211a3236eb02abcdb136c.zip | |
New bytecode implementation of mruby VM.
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 100 | ||||
| -rw-r--r-- | src/vm.c | 16 |
2 files changed, 113 insertions, 3 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index b8caba3a0..8e72abda2 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -445,8 +445,108 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) break; default: goto normal; +======= +struct mrb_insn_data { + uint8_t insn; + uint16_t a; + uint16_t b; + uint8_t c; +}; + +struct mrb_insn_data +mrb_decode_insn(codegen_scope *s, mrb_code *pc) +{ + struct mrb_insn_data data = { 0 }; + mrb_code insn = READ_B(); + uint16_t a = 0; + uint16_t b = 0; + uint8_t c = 0; + + switch (insn) { +#define FETCH_Z() /* empty */ +#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x (); break; +#include "mruby/ops.h" +#undef OPCODE + } + switch (insn) { + case OP_EXT1: + insn = READ_B(); + switch (insn) { +#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); break; +#include "mruby/ops.h" +#undef OPCODE + } + break; + case OP_EXT2: + insn = READ_B(); + switch (insn) { +#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); break; +#include "mruby/ops.h" +#undef OPCODE + } + break; + case OP_EXT3: + insn = READ_B(); + switch (insn) { +#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); break; +#include "mruby/ops.h" +#undef OPCODE + } + break; + default: + break; + } + data.insn = insn; + data.a = a; + data.b = b; + data.c = c; + return data; +} + +struct mrb_insn_data +mrb_last_insn(codegen_scope *s) +{ + if (s->pc == s->lastpc) { + struct mrb_insn_data data; + + data.insn = OP_NOP; + return data; + } + return mrb_decode_insn(s, &s->iseq[s->lastpc]); +} + +static mrb_bool +no_peephole(codegen_scope *s) +{ + return no_optimize(s) || s->lastlabel == s->pc || s->pc == 0 || s->pc == s->lastpc; +} + +static uint16_t +genjmp(codegen_scope *s, mrb_code i, uint16_t pc) +{ + uint16_t pos; + + s->lastpc = s->pc; + gen_B(s, i); + pos = s->pc; + gen_S(s, pc); + return pos; +} + +static uint16_t +genjmp2(codegen_scope *s, mrb_code i, uint16_t a, int pc, int val) +{ + uint16_t pos; + + if (!no_peephole(s) && !val) { + struct mrb_insn_data data = mrb_last_insn(s); + + if (data.insn == OP_MOVE && data.a == a) { + s->pc = s->lastpc; + a = data.b; } } + return genop(s, i); } static void @@ -1069,6 +1069,16 @@ RETRY_TRY_BLOCK: NEXT; } + CASE(OP_LOADI, BB) { + SET_INT_VALUE(regs[a], b); + NEXT; + } + + CASE(OP_LOADINEG, BB) { + SET_INT_VALUE(regs[a], -b); + NEXT; + } + CASE(OP_LOADI__1,B) goto L_LOADI; CASE(OP_LOADI_0,B) goto L_LOADI; CASE(OP_LOADI_1,B) goto L_LOADI; @@ -1131,12 +1141,12 @@ RETRY_TRY_BLOCK: } CASE(OP_GETIV, BB) { - regs[a] = mrb_vm_iv_get(mrb, syms[b]); + regs[a] = mrb_iv_get(mrb, regs[0], syms[b]); NEXT; } CASE(OP_SETIV, BB) { - mrb_vm_iv_set(mrb, syms[b], regs[a]); + mrb_iv_set(mrb, regs[0], syms[b], regs[a]); NEXT; } @@ -2470,7 +2480,7 @@ RETRY_TRY_BLOCK: #ifdef MRB_WORD_BOXING { mrb_float x = mrb_float(regs[a]); - SET_FLOAT_VALUE(mrb, regs[a], x - GETARG_C(i)); + SET_FLOAT_VALUE(mrb, regs[a], x - c); } #else mrb_float(regs_a[0]) -= c; |
