Merge pull request #870 from mattn/regexp_compile

Regexp compile
This commit is contained in:
Yukihiro "Matz" Matsumoto
2013-02-22 06:12:52 -08:00
+147 -147
View File
@@ -168,8 +168,8 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
switch (c1) {
case OP_MOVE:
if (GETARG_A(i) == GETARG_B(i)) {
/* skip useless OP_MOVE */
return;
/* skip useless OP_MOVE */
return;
}
if (val) break;
switch (c0) {
@@ -178,10 +178,10 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
/* skip swapping OP_MOVE */
return;
}
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
s->iseq[s->pc-1] = MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0));
return;
}
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
s->iseq[s->pc-1] = MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0));
return;
}
break;
case OP_LOADI:
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
@@ -229,7 +229,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
}
break;
default:
break;
break;
}
break;
case OP_SETIV:
@@ -269,33 +269,33 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
case OP_RETURN:
switch (c0) {
case OP_RETURN:
return;
return;
case OP_MOVE:
s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL);
return;
s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL);
return;
case OP_LOADI:
s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, 0, GETARG_sBx(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, 0, GETARG_sBx(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
case OP_ARRAY:
case OP_HASH:
case OP_RANGE:
case OP_AREF:
case OP_GETUPVAR:
s->iseq[s->pc-1] = MKOP_ABC(c0, 0, GETARG_B(i0), GETARG_C(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
s->iseq[s->pc-1] = MKOP_ABC(c0, 0, GETARG_B(i0), GETARG_C(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
case OP_SETIV:
case OP_SETCV:
case OP_SETCONST:
case OP_SETMCNST:
case OP_SETUPVAR:
case OP_SETGLOBAL:
s->pc--;
genop_peep(s, i0, NOVAL);
i0 = s->iseq[s->pc-1];
genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL));
return;
s->pc--;
genop_peep(s, i0, NOVAL);
i0 = s->iseq[s->pc-1];
genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL));
return;
case OP_LOADSYM:
case OP_GETGLOBAL:
case OP_GETIV:
@@ -304,37 +304,37 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
case OP_GETSPECIAL:
case OP_LOADL:
case OP_STRING:
s->iseq[s->pc-1] = MKOP_ABx(c0, 0, GETARG_Bx(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
s->iseq[s->pc-1] = MKOP_ABx(c0, 0, GETARG_Bx(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
case OP_SCLASS:
s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
case OP_LOADNIL:
case OP_LOADSELF:
case OP_LOADT:
case OP_LOADF:
case OP_OCLASS:
s->iseq[s->pc-1] = MKOP_A(c0, 0);
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
s->iseq[s->pc-1] = MKOP_A(c0, 0);
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
default:
break;
break;
}
break;
case OP_ADD:
case OP_SUB:
if (c0 == OP_LOADI) {
int c = GETARG_sBx(i0);
if (c1 == OP_SUB) c = -c;
if (c > 127 || c < -127) break;
if (0 <= c)
s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c);
else
s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c);
return;
int c = GETARG_sBx(i0);
if (c1 == OP_SUB) c = -c;
if (c > 127 || c < -127) break;
if (0 <= c)
s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c);
else
s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c);
return;
}
default:
break;
@@ -419,7 +419,7 @@ new_lit(codegen_scope *s, mrb_value val)
}
s->irep->pool[s->irep->plen] = val;
i = s->irep->plen++;
return i;
}
@@ -681,33 +681,33 @@ gen_values(codegen_scope *s, node *t, int val)
while (t) {
if ((intptr_t)t->car->car == NODE_SPLAT) { // splat mode
if (val) {
pop_n(n);
genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));
push();
codegen(s, t->car, VAL);
pop(); pop();
genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
t = t->cdr;
while (t) {
push();
codegen(s, t->car, VAL);
pop(); pop();
if ((intptr_t)t->car->car == NODE_SPLAT) {
genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
}
else {
genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
}
t = t->cdr;
}
pop_n(n);
genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));
push();
codegen(s, t->car, VAL);
pop(); pop();
genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
t = t->cdr;
while (t) {
push();
codegen(s, t->car, VAL);
pop(); pop();
if ((intptr_t)t->car->car == NODE_SPLAT) {
genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
}
else {
genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
}
t = t->cdr;
}
}
else {
codegen(s, t->car->cdr, NOVAL);
t = t->cdr;
while (t) {
codegen(s, t->car, NOVAL);
t = t->cdr;
}
codegen(s, t->car->cdr, NOVAL);
t = t->cdr;
while (t) {
codegen(s, t->car, NOVAL);
t = t->cdr;
}
}
return -1;
}
@@ -792,11 +792,11 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val)
}
else {
if (sendv) n = CALL_MAXARGS;
if (blk > 0) { /* no block */
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n));
if (blk > 0) { /* no block */
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n));
}
else {
genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, n));
genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, n));
}
}
}
@@ -947,9 +947,9 @@ readint_float(codegen_scope *s, const char *p, int base)
c = tolower((unsigned char)c);
for (n=0; n<base; n++) {
if (mrb_digitmap[n] == c) {
f *= base;
f += n;
break;
f *= base;
f += n;
break;
}
}
if (n == base) {
@@ -973,7 +973,7 @@ readint_mrb_int(codegen_scope *s, const char *p, int base, int neg, int *overflo
c = tolower((unsigned char)c);
for (n=0; n<base; n++) {
if (mrb_digitmap[n] == c) {
break;
break;
}
}
if (n == base) {
@@ -1034,7 +1034,7 @@ codegen(codegen_scope *s, node *tree, int val)
lp->pc1 = onerr;
if (tree->car) {
codegen(s, tree->car, val);
if (val) pop();
if (val) pop();
}
lp->type = LOOP_RESCUE;
noexc = new_label(s);
@@ -1166,16 +1166,16 @@ codegen(codegen_scope *s, node *tree, int val)
else {
if (val) {
pop();
pos2 = new_label(s);
genop(s, MKOP_sBx(OP_JMP, 0));
dispatch(s, pos1);
pos2 = new_label(s);
genop(s, MKOP_sBx(OP_JMP, 0));
dispatch(s, pos1);
genop(s, MKOP_A(OP_LOADNIL, cursp()));
dispatch(s, pos2);
dispatch(s, pos2);
push();
}
else {
dispatch(s, pos1);
}
else {
dispatch(s, pos1);
}
}
}
break;
@@ -1268,8 +1268,8 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "===")), 1));
}
else {
pop();
}
pop();
}
tmp = new_label(s);
genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
pos2 = tmp;
@@ -1281,7 +1281,7 @@ codegen(codegen_scope *s, node *tree, int val)
dispatch_linked(s, pos2);
}
codegen(s, tree->car->cdr, val);
if (val) pop();
if (val) pop();
tmp = new_label(s);
genop(s, MKOP_sBx(OP_JMP, pos3));
pos3 = tmp;
@@ -1289,8 +1289,8 @@ codegen(codegen_scope *s, node *tree, int val)
tree = tree->cdr;
}
if (val) {
genop(s, MKOP_A(OP_LOADNIL, cursp()));
push();
genop(s, MKOP_A(OP_LOADNIL, cursp()));
push();
}
if (pos3) dispatch_linked(s, pos3);
}
@@ -1353,7 +1353,7 @@ codegen(codegen_scope *s, node *tree, int val)
n = gen_values(s, tree, val);
if (n >= 0) {
if (val) {
pop_n(n);
pop_n(n);
genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));
push();
}
@@ -1375,7 +1375,7 @@ codegen(codegen_scope *s, node *tree, int val)
tree = tree->cdr;
}
if (val) {
pop_n(len*2);
pop_n(len*2);
genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len));
push();
}
@@ -1465,18 +1465,18 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, tree->car, VAL);
if (len == 2 &&
((name[0] == '|' && name[1] == '|') ||
(name[0] == '&' && name[1] == '&'))) {
int pos;
((name[0] == '|' && name[1] == '|') ||
(name[0] == '&' && name[1] == '&'))) {
int pos;
pop();
pos = new_label(s);
genop(s, MKOP_AsBx(name[0] == '|' ? OP_JMPIF : OP_JMPNOT, cursp(), 0));
codegen(s, tree->cdr->cdr->car, VAL);
pop();
gen_assignment(s, tree->car, cursp(), val);
dispatch(s, pos);
break;
pop();
pos = new_label(s);
genop(s, MKOP_AsBx(name[0] == '|' ? OP_JMPIF : OP_JMPNOT, cursp(), 0));
codegen(s, tree->cdr->cdr->car, VAL);
pop();
gen_assignment(s, tree->car, cursp(), val);
dispatch(s, pos);
break;
}
codegen(s, tree->cdr->cdr->car, VAL);
pop(); pop();
@@ -1501,7 +1501,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_ABC(OP_GE, cursp(), idx, 1));
}
else {
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1));
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1));
}
}
gen_assignment(s, tree->car, cursp(), val);
@@ -1511,16 +1511,16 @@ codegen(codegen_scope *s, node *tree, int val)
{
int n = 0, noop = 0, sendv = 0;
push(); /* room for receiver */
push(); /* room for receiver */
if (tree) {
node *args = tree->car;
if (args) {
n = gen_values(s, args, VAL);
if (n < 0) {
n = noop = sendv = 1;
push();
}
}
if (args) {
n = gen_values(s, args, VAL);
if (n < 0) {
n = noop = sendv = 1;
push();
}
}
}
if (tree && tree->cdr) {
codegen(s, tree->cdr, VAL);
@@ -1541,7 +1541,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen_scope *s2 = s;
int lv = 0, ainfo = 0;
push(); /* room for receiver */
push(); /* room for receiver */
while (!s2->mscope) {
lv++;
s2 = s2->prev;
@@ -1550,7 +1550,7 @@ codegen(codegen_scope *s, node *tree, int val)
if (s2) ainfo = s2->ainfo;
genop(s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)));
if (tree && tree->cdr) {
push();
push();
codegen(s, tree->cdr, VAL);
pop_n(2);
}
@@ -1782,20 +1782,20 @@ codegen(codegen_scope *s, node *tree, int val)
i = readint_mrb_int(s, p, base, FALSE, &overflow);
if (overflow) {
double f = readint_float(s, p, base);
int off = new_lit(s, mrb_float_value(f));
double f = readint_float(s, p, base);
int off = new_lit(s, mrb_float_value(f));
genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
}
else {
if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i);
}
else {
int off = new_lit(s, mrb_fixnum_value(i));
co = MKOP_ABx(OP_LOADL, cursp(), off);
}
genop(s, co);
if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i);
}
else {
int off = new_lit(s, mrb_fixnum_value(i));
co = MKOP_ABx(OP_LOADL, cursp(), off);
}
genop(s, co);
}
push();
}
@@ -1838,21 +1838,21 @@ codegen(codegen_scope *s, node *tree, int val)
i = readint_mrb_int(s, p, base, TRUE, &overflow);
if (overflow) {
double f = readint_float(s, p, base);
int off = new_lit(s, mrb_float_value(-f));
double f = readint_float(s, p, base);
int off = new_lit(s, mrb_float_value(-f));
genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
}
else {
if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i);
}
else {
int off = new_lit(s, mrb_fixnum_value(i));
co = MKOP_ABx(OP_LOADL, cursp(), off);
}
genop(s, co);
}
genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
}
else {
if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i);
}
else {
int off = new_lit(s, mrb_fixnum_value(i));
co = MKOP_ABx(OP_LOADL, cursp(), off);
}
genop(s, co);
}
push();
}
break;
@@ -1925,14 +1925,14 @@ codegen(codegen_scope *s, node *tree, int val)
push();
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
if (p2) {
push();
off = new_lit(s, mrb_str_new(s->mrb, p2, strlen(p2)));
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
n++;
pop();
push();
off = new_lit(s, mrb_str_new(s->mrb, p2, strlen(p2)));
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
n++;
pop();
}
pop();
sym = new_sym(s, mrb_intern(s->mrb, "new"));
sym = new_sym(s, mrb_intern(s->mrb, "compile"));
genop(s, MKOP_ABC(OP_SEND, cursp(), sym, n));
mrb_gc_arena_restore(s->mrb, ai);
push();
@@ -2178,7 +2178,7 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
p->irep->slen = 0;
p->lv = lv;
p->sp += node_len(lv)+1; /* add self */
p->sp += node_len(lv)+1; /* add self */
p->nlocals = p->sp;
p->ai = mrb_gc_arena_save(mrb);
@@ -2195,7 +2195,7 @@ scope_finish(codegen_scope *s)
{
mrb_state *mrb = s->mrb;
mrb_irep *irep = s->irep;
irep->flags = 0;
if (s->iseq) {
irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc);
@@ -2540,10 +2540,10 @@ codedump(mrb_state *mrb, int n)
break;
case OP_STRING:
{
mrb_value s = irep->pool[GETARG_Bx(c)];
s = mrb_str_dump(mrb, s);
printf("OP_STRING\tR%d\t%s\n", GETARG_A(c), RSTRING_PTR(s));
mrb_value s = irep->pool[GETARG_Bx(c)];
s = mrb_str_dump(mrb, s);
printf("OP_STRING\tR%d\t%s\n", GETARG_A(c), RSTRING_PTR(s));
}
break;
case OP_STRCAT: