summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-eval
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2018-05-24 15:19:06 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2018-07-30 22:57:54 +0900
commit891839b976c75c77f238931123ac472e3284e95d (patch)
treebbecccdb4cea0f3272a966e39cdfebfda7eb5295 /mrbgems/mruby-eval
parentb09d2eb90074c50ed83d4d10d3fe0393bc9e43da (diff)
downloadmruby-891839b976c75c77f238931123ac472e3284e95d.tar.gz
mruby-891839b976c75c77f238931123ac472e3284e95d.zip
New bytecode implementation of mruby VM.
Diffstat (limited to 'mrbgems/mruby-eval')
-rw-r--r--mrbgems/mruby-eval/src/eval.c112
1 files changed, 75 insertions, 37 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
index 5c8e78acd..42a4183b7 100644
--- a/mrbgems/mruby-eval/src/eval.c
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -44,7 +44,7 @@ search_irep(mrb_irep *top, int bnest, int lev, mrb_irep *bottom)
return NULL;
}
-static inline mrb_code
+static uint16_t
search_variable(mrb_state *mrb, mrb_sym vsym, int bnest)
{
mrb_irep *virep;
@@ -57,7 +57,7 @@ search_variable(mrb_state *mrb, mrb_sym vsym, int bnest)
}
for (pos = 0; pos < virep->nlocals - 1; pos++) {
if (vsym == virep->lv[pos].name) {
- return (MKARG_B(pos + 1) | MKARG_C(level + bnest));
+ return (pos+1)<<8 | (level+bnest);
}
}
}
@@ -71,8 +71,8 @@ irep_argc(mrb_irep *irep)
mrb_code c;
c = irep->iseq[0];
- if (GET_OPCODE(c) == OP_ENTER) {
- mrb_aspec ax = GETARG_Ax(c);
+ if (c == OP_ENTER) {
+ mrb_aspec ax = PEEK_W(irep->iseq+1);
/* extra 1 means a slot for block */
return MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1;
}
@@ -88,95 +88,132 @@ potential_upvar_p(struct mrb_locals *lv, uint16_t v, int argc, uint16_t nlocals)
return TRUE;
}
+extern uint8_t mrb_insn_size[];
+extern uint8_t mrb_insn_size1[];
+extern uint8_t mrb_insn_size2[];
+extern uint8_t mrb_insn_size3[];
+
static void
patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest, mrb_irep *top)
{
int i;
- mrb_code c;
+ uint32_t a;
+ uint16_t b;
+ uint8_t c;
+ mrb_code insn;
int argc = irep_argc(irep);
- for (i = 0; i < irep->ilen; i++) {
- c = irep->iseq[i];
- switch(GET_OPCODE(c)){
+ for (i = 0; i < irep->ilen; ) {
+ insn = irep->iseq[i];
+ switch(insn){
case OP_EPUSH:
- patch_irep(mrb, irep->reps[GETARG_Bx(c)], bnest + 1, top);
+ b = PEEK_S(irep->iseq+i+1);
+ patch_irep(mrb, irep->reps[b], bnest + 1, top);
break;
case OP_LAMBDA:
- {
- int arg_c = GETARG_c(c);
- if (arg_c & OP_L_CAPTURE) {
- patch_irep(mrb, irep->reps[GETARG_b(c)], bnest + 1, top);
- }
- }
+ case OP_BLOCK:
+ a = PEEK_B(irep->iseq+i+1);
+ b = PEEK_B(irep->iseq+i+2);
+ patch_irep(mrb, irep->reps[b], bnest + 1, top);
break;
case OP_SEND:
- if (GETARG_C(c) != 0) {
+ b = PEEK_B(irep->iseq+i+2);
+ c = PEEK_B(irep->iseq+i+3);
+ if (c != 0) {
break;
}
else {
- mrb_code arg = search_variable(mrb, irep->syms[GETARG_B(c)], bnest);
+ uint16_t arg = search_variable(mrb, irep->syms[b], bnest);
if (arg != 0) {
/* must replace */
- irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
+ irep->iseq[i] = OP_GETUPVAR;
+ irep->iseq[i+2] = arg >> 8;
+ irep->iseq[i+3] = arg & 0xff;
}
}
break;
case OP_MOVE:
+ a = PEEK_B(irep->iseq+i+1);
+ b = PEEK_B(irep->iseq+i+2);
/* src part */
- if (potential_upvar_p(irep->lv, GETARG_B(c), argc, irep->nlocals)) {
- mrb_code arg = search_variable(mrb, irep->lv[GETARG_B(c) - 1].name, bnest);
+ if (potential_upvar_p(irep->lv, b, argc, irep->nlocals)) {
+ uint16_t arg = search_variable(mrb, irep->lv[b - 1].name, bnest);
if (arg != 0) {
/* must replace */
- irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
+ irep->iseq[i] = insn = OP_GETUPVAR;
+ irep->iseq[i+2] = arg >> 8;
+ irep->iseq[i+3] = arg & 0xff;
}
}
/* dst part */
- if (potential_upvar_p(irep->lv, GETARG_A(c), argc, irep->nlocals)) {
- mrb_code arg = search_variable(mrb, irep->lv[GETARG_A(c) - 1].name, bnest);
+ if (potential_upvar_p(irep->lv, a, argc, irep->nlocals)) {
+ uint16_t arg = search_variable(mrb, irep->lv[a - 1].name, bnest);
if (arg != 0) {
/* must replace */
- irep->iseq[i] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_B(c)) | arg;
+ irep->iseq[i] = insn = OP_SETUPVAR;
+ irep->iseq[i+1] = b;
+ irep->iseq[i+2] = arg >> 8;
+ irep->iseq[i+3] = arg & 0xff;
}
}
break;
case OP_GETUPVAR:
+ a = PEEK_B(irep->iseq+i+1);
+ b = PEEK_B(irep->iseq+i+2);
+ c = PEEK_B(irep->iseq+i+3);
{
- int lev = GETARG_C(c)+1;
+ int lev = c+1;
mrb_irep *tmp = search_irep(top, bnest, lev, irep);
- if (potential_upvar_p(tmp->lv, GETARG_B(c), irep_argc(tmp), tmp->nlocals)) {
- mrb_code arg = search_variable(mrb, tmp->lv[GETARG_B(c)-1].name, bnest);
+ if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) {
+ mrb_code arg = search_variable(mrb, tmp->lv[b-1].name, bnest);
if (arg != 0) {
/* must replace */
- irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
+ irep->iseq[i] = OP_GETUPVAR;
+ irep->iseq[i+2] = arg >> 8;
+ irep->iseq[i+3] = arg & 0xff;
}
}
}
break;
case OP_SETUPVAR:
+ a = PEEK_B(irep->iseq+i+1);
+ b = PEEK_B(irep->iseq+i+2);
+ c = PEEK_B(irep->iseq+i+3);
{
- int lev = GETARG_C(c)+1;
+ int lev = c+1;
mrb_irep *tmp = search_irep(top, bnest, lev, irep);
- if (potential_upvar_p(tmp->lv, GETARG_B(c), irep_argc(tmp), tmp->nlocals)) {
- mrb_code arg = search_variable(mrb, tmp->lv[GETARG_B(c)-1].name, bnest);
+ if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) {
+ mrb_code arg = search_variable(mrb, tmp->lv[b-1].name, bnest);
if (arg != 0) {
/* must replace */
- irep->iseq[i] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
+ irep->iseq[i] = OP_SETUPVAR;
+ irep->iseq[i+1] = a;
+ irep->iseq[i+2] = arg >> 8;
+ irep->iseq[i+3] = arg & 0xff;
}
}
}
break;
- case OP_STOP:
- if (mrb->c->ci->acc >= 0) {
- irep->iseq[i] = MKOP_AB(OP_RETURN, irep->nlocals, OP_R_NORMAL);
- }
- break;
+ case OP_EXT1:
+ insn = PEEK_B(irep->iseq+1);
+ i += mrb_insn_size1[insn];
+ continue;
+ case OP_EXT2:
+ insn = PEEK_B(irep->iseq+1);
+ i += mrb_insn_size2[insn];
+ continue;
+ case OP_EXT3:
+ insn = PEEK_B(irep->iseq+1);
+ i += mrb_insn_size3[insn];
+ continue;
}
+ i+=mrb_insn_size[insn];
}
}
@@ -203,6 +240,7 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
mrbc_filename(mrb, cxt, file ? file : "(eval)");
cxt->capture_errors = TRUE;
cxt->no_optimize = TRUE;
+ cxt->on_eval = TRUE;
p = mrb_parse_nstring(mrb, s, len, cxt);