mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
New bytecode implementation of mruby VM.
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user