summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c100
-rw-r--r--src/vm.c16
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
diff --git a/src/vm.c b/src/vm.c
index b8feb52db..d206f9675 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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;