diff options
| -rw-r--r-- | include/mruby/ops.h | 3 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 67 | ||||
| -rw-r--r-- | src/codedump.c | 9 | ||||
| -rw-r--r-- | src/vm.c | 17 |
4 files changed, 73 insertions, 23 deletions
diff --git a/include/mruby/ops.h b/include/mruby/ops.h index 75936a791..43b8de638 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -14,6 +14,7 @@ operation code operands semantics OPCODE(NOP, Z) /* no operation */ OPCODE(MOVE, BB) /* R(a) = R(b) */ OPCODE(LOADL, BB) /* R(a) = Pool(b) */ +OPCODE(LOADL16, BS) /* R(a) = Pool(b) */ OPCODE(LOADI, BB) /* R(a) = mrb_int(b) */ OPCODE(LOADINEG, BB) /* R(a) = mrb_int(-b) */ OPCODE(LOADI__1, B) /* R(a) = mrb_int(-1) */ @@ -27,6 +28,7 @@ OPCODE(LOADI_6, B) /* R(a) = mrb_int(6) */ OPCODE(LOADI_7, B) /* R(a) = mrb_int(7) */ OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */ OPCODE(LOADSYM, BB) /* R(a) = Syms(b) */ +OPCODE(LOADSYM16, BS) /* R(a) = Syms(b) */ OPCODE(LOADNIL, B) /* R(a) = nil */ OPCODE(LOADSELF, B) /* R(a) = self */ OPCODE(LOADT, B) /* R(a) = true */ @@ -89,6 +91,7 @@ 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(STRING, BB) /* R(a) = str_dup(Lit(b)) */ +OPCODE(STRING16, BS) /* R(a) = str_dup(Lit(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)) */ OPCODE(HASHADD, BB) /* R(a) = hash_push(R(a),R(a+1)..R(a+b*2)) */ diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index eb37cd701..5dfb6c121 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -248,6 +248,27 @@ genop_2(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b) } } +/* similar to `genop_2` but generate `genop_2S` with `i+1` */ +/* works for OP_LOADL, OP_LOADSYM, OP_STRING */ +static void +genop_bs(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b) +{ + s->lastpc = s->pc; + if (a > 0xff || b > 0xffff) { + codegen_error(s, "too big operand"); + } + if (b > 0xff) { + gen_B(s, i+1); + gen_B(s, (uint8_t)a); + gen_S(s, b); + } + else { + gen_B(s, i); + gen_B(s, (uint8_t)a); + gen_B(s, (uint8_t)b); + } +} + static void genop_3(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b, uint8_t c) { @@ -394,9 +415,11 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) s->pc = s->lastpc; genop_1(s, data.insn, dst); break; - case OP_LOADI: case OP_LOADINEG: case OP_LOADL: case OP_LOADSYM: + case OP_LOADI: case OP_LOADINEG: + case OP_LOADL: case OP_LOADSYM: + case OP_LOADL16: case OP_LOADSYM16: case OP_GETGV: case OP_GETSV: case OP_GETIV: case OP_GETCV: - case OP_GETCONST: case OP_STRING: + case OP_GETCONST: case OP_STRING: case OP_STRING16: case OP_LAMBDA: case OP_BLOCK: case OP_METHOD: case OP_BLKPUSH: if (nopeep || data.a != src || data.a < s->nlocals) goto normal; s->pc = s->lastpc; @@ -611,9 +634,6 @@ new_lit(codegen_scope *s, mrb_value val) return i; } -/* maximum symbol numbers */ -#define MAXSYMLEN 0x10000 - static int new_sym(codegen_scope *s, mrb_sym sym) { @@ -627,6 +647,9 @@ new_sym(codegen_scope *s, mrb_sym sym) } if (s->irep->slen >= s->scapa) { s->scapa *= 2; + if (s->scapa > 0xffff) { + codegen_error(s, "too many symbols"); + } s->syms = (mrb_sym*)codegen_realloc(s, s->syms, sizeof(mrb_sym)*s->scapa); } s->syms[s->irep->slen] = sym; @@ -2447,7 +2470,7 @@ codegen(codegen_scope *s, node *tree, int val) double f = readint_float(s, p, base); int off = new_lit(s, mrb_float_value(s->mrb, f)); - genop_2(s, OP_LOADL, cursp(), off); + genop_bs(s, OP_LOADL, cursp(), off); } else #endif @@ -2466,7 +2489,7 @@ codegen(codegen_scope *s, node *tree, int val) lit_int: off = new_lit(s, mrb_int_value(s->mrb, i)); - genop_2(s, OP_LOADL, cursp(), off); + genop_bs(s, OP_LOADL, cursp(), off); } } push(); @@ -2480,7 +2503,7 @@ codegen(codegen_scope *s, node *tree, int val) mrb_float f = mrb_float_read(p, NULL); int off = new_lit(s, mrb_float_value(s->mrb, f)); - genop_2(s, OP_LOADL, cursp(), off); + genop_bs(s, OP_LOADL, cursp(), off); push(); } break; @@ -2497,7 +2520,7 @@ codegen(codegen_scope *s, node *tree, int val) mrb_float f = mrb_float_read(p, NULL); int off = new_lit(s, mrb_float_value(s->mrb, -f)); - genop_2(s, OP_LOADL, cursp(), off); + genop_bs(s, OP_LOADL, cursp(), off); push(); } break; @@ -2516,7 +2539,7 @@ codegen(codegen_scope *s, node *tree, int val) double f = readint_float(s, p, base); int off = new_lit(s, mrb_float_value(s->mrb, -f)); - genop_2(s, OP_LOADL, cursp(), off); + genop_bs(s, OP_LOADL, cursp(), off); } else { #endif @@ -2529,7 +2552,7 @@ codegen(codegen_scope *s, node *tree, int val) } else { int off = new_lit(s, mrb_int_value(s->mrb, i)); - genop_2(s, OP_LOADL, cursp(), off); + genop_bs(s, OP_LOADL, cursp(), off); } #ifndef MRB_NO_FLOAT } @@ -2562,7 +2585,7 @@ codegen(codegen_scope *s, node *tree, int val) int off = new_lit(s, mrb_str_new(s->mrb, p, len)); mrb_gc_arena_restore(s->mrb, ai); - genop_2(s, OP_STRING, cursp(), off); + genop_bs(s, OP_STRING, cursp(), off); push(); } break; @@ -2649,7 +2672,7 @@ codegen(codegen_scope *s, node *tree, int val) genop_1(s, OP_LOADSELF, cursp()); push(); - genop_2(s, OP_STRING, cursp(), off); + genop_bs(s, OP_STRING, cursp(), off); push(); push(); pop_n(3); sym = new_sym(s, MRB_QSYM(tick)); /* ` */ @@ -2672,12 +2695,12 @@ codegen(codegen_scope *s, node *tree, int val) genop_1(s, OP_OCLASS, cursp()); genop_2(s, OP_GETMCNST, cursp(), sym); push(); - genop_2(s, OP_STRING, cursp(), off); + genop_bs(s, OP_STRING, cursp(), off); push(); if (p2 || p3) { if (p2) { /* opt */ off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); - genop_2(s, OP_STRING, cursp(), off); + genop_bs(s, OP_STRING, cursp(), off); } else { genop_1(s, OP_LOADNIL, cursp()); @@ -2686,7 +2709,7 @@ codegen(codegen_scope *s, node *tree, int val) argc++; if (p3) { /* enc */ off = new_lit(s, mrb_str_new(s->mrb, p3, 1)); - genop_2(s, OP_STRING, cursp(), off); + genop_bs(s, OP_STRING, cursp(), off); push(); argc++; } @@ -2726,7 +2749,7 @@ codegen(codegen_scope *s, node *tree, int val) p = (char*)n->car; off = new_lit(s, mrb_str_new_cstr(s->mrb, p)); codegen(s, tree->car, VAL); - genop_2(s, OP_STRING, cursp(), off); + genop_bs(s, OP_STRING, cursp(), off); pop(); genop_1(s, OP_STRCAT, cursp()); push(); @@ -2734,14 +2757,14 @@ codegen(codegen_scope *s, node *tree, int val) if (n->cdr->car) { /* opt */ char *p2 = (char*)n->cdr->car; off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); - genop_2(s, OP_STRING, cursp(), off); + genop_bs(s, OP_STRING, cursp(), off); push(); argc++; } if (n->cdr->cdr) { /* enc */ char *p2 = (char*)n->cdr->cdr; off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); - genop_2(s, OP_STRING, cursp(), off); + genop_bs(s, OP_STRING, cursp(), off); push(); argc++; } @@ -2768,7 +2791,7 @@ codegen(codegen_scope *s, node *tree, int val) if (val) { int sym = new_sym(s, nsym(tree)); - genop_2(s, OP_LOADSYM, cursp(), sym); + genop_bs(s, OP_LOADSYM, cursp(), sym); push(); } break; @@ -2942,7 +2965,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); genop_2(s, OP_DEF, cursp(), sym); if (val) { - genop_2(s, OP_LOADSYM, cursp(), sym); + genop_bs(s, OP_LOADSYM, cursp(), sym); push(); } } @@ -2962,7 +2985,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); genop_2(s, OP_DEF, cursp(), sym); if (val) { - genop_2(s, OP_LOADSYM, cursp(), sym); + genop_bs(s, OP_LOADSYM, cursp(), sym); push(); } } diff --git a/src/codedump.c b/src/codedump.c index dcc196973..9af609264 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -135,7 +135,10 @@ codedump(mrb_state *mrb, const mrb_irep *irep) printf("OP_MOVE\tR%d\tR%d\t", a, b); print_lv_ab(mrb, irep, a, b); break; + CASE(OP_LOADL16, BS); + goto op_loadl; CASE(OP_LOADL, BB); + op_loadl: switch (irep->pool[b].tt) { case IREP_TT_FLOAT: printf("OP_LOADL\tR%d\tL(%d)\t; %f", a, b, (double)irep->pool[b].u.f); @@ -182,7 +185,10 @@ codedump(mrb_state *mrb, const mrb_irep *irep) printf("OP_LOADI_%d\tR%d\t\t", ins-(int)OP_LOADI_0, a); print_lv_a(mrb, irep, a); break; + CASE(OP_LOADSYM16, BS); + goto op_loadsym; CASE(OP_LOADSYM, BB); + op_loadsym: printf("OP_LOADSYM\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; @@ -438,7 +444,10 @@ codedump(mrb_state *mrb, const mrb_irep *irep) printf("OP_INTERN\tR%d", a); print_lv_a(mrb, irep, a); break; + CASE(OP_STRING16, BS); + goto op_string; CASE(OP_STRING, BB); + op_string: 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); } @@ -1069,7 +1069,12 @@ RETRY_TRY_BLOCK: NEXT; } + + CASE(OP_LOADL16, BS) { + goto op_loadl; + } CASE(OP_LOADL, BB) { + op_loadl: switch (pool[b].tt) { /* number */ case IREP_TT_INT32: regs[a] = mrb_int_value(mrb, (mrb_int)pool[b].u.i32); @@ -1138,6 +1143,11 @@ RETRY_TRY_BLOCK: NEXT; } + CASE(OP_LOADSYM16, BS) { + SET_SYM_VALUE(regs[a], syms[b]); + NEXT; + } + CASE(OP_LOADNIL, B) { SET_NIL_VALUE(regs[a]); NEXT; @@ -2575,8 +2585,13 @@ RETRY_TRY_BLOCK: NEXT; } + CASE(OP_STRING16, BS) { + goto op_string; + } CASE(OP_STRING, BB) { - size_t len = pool[b].tt >> 2; + size_t len; + op_string: + len = pool[b].tt >> 2; if (pool[b].tt & IREP_TT_SFLAG) { regs[a] = mrb_str_new_static(mrb, pool[b].u.str, len); } |
