codegen.c: unify `OP_ARYPUSH` and `OP_ARYPUSH_N`.

- `OP_ARYPUSH` now takes operand for the number of pushing elements
- the code generator consume the stack no more than `64` for `mruby/c`
parent 7c99df84
...@@ -97,8 +97,7 @@ sign) of operands. ...@@ -97,8 +97,7 @@ sign) of operands.
| `OP_ARRAY` | `BB` | `R(a) = ary_new(R(a),R(a+1)..R(a+b))` | | `OP_ARRAY` | `BB` | `R(a) = ary_new(R(a),R(a+1)..R(a+b))` |
| `OP_ARRAY2` | `BBB` | `R(a) = ary_new(R(b),R(b+1)..R(b+c))` | | `OP_ARRAY2` | `BBB` | `R(a) = ary_new(R(b),R(b+1)..R(b+c))` |
| `OP_ARYCAT` | `B` | `ary_cat(R(a),R(a+1))` | | `OP_ARYCAT` | `B` | `ary_cat(R(a),R(a+1))` |
| `OP_ARYPUSH` | `B` | `ary_push(R(a),R(a+1))` | | `OP_ARYPUSH` | `BB` | `ary_push(R(a),R(a+1)..R(a+b))` |
| `OP_ARYPUSH_N` | `BB` | `ary_push(R(a),R(a+1)..R(a+b))` |
| `OP_ARYDUP` | `B` | `R(a) = ary_dup(R(a))` | | `OP_ARYDUP` | `B` | `R(a) = ary_dup(R(a))` |
| `OP_AREF` | `BBB` | `R(a) = R(b)[c]` | | `OP_AREF` | `BBB` | `R(a) = R(b)[c]` |
| `OP_ASET` | `BBB` | `R(a)[c] = R(b)` | | `OP_ASET` | `BBB` | `R(a)[c] = R(b)` |
......
...@@ -85,8 +85,7 @@ OPCODE(GE, B) /* R(a) = R(a)>=R(a+1) */ ...@@ -85,8 +85,7 @@ OPCODE(GE, B) /* R(a) = R(a)>=R(a+1) */
OPCODE(ARRAY, BB) /* R(a) = ary_new(R(a),R(a+1)..R(a+b)) */ OPCODE(ARRAY, BB) /* R(a) = ary_new(R(a),R(a+1)..R(a+b)) */
OPCODE(ARRAY2, BBB) /* R(a) = ary_new(R(b),R(b+1)..R(b+c)) */ OPCODE(ARRAY2, BBB) /* R(a) = ary_new(R(b),R(b+1)..R(b+c)) */
OPCODE(ARYCAT, B) /* ary_cat(R(a),R(a+1)) */ OPCODE(ARYCAT, B) /* ary_cat(R(a),R(a+1)) */
OPCODE(ARYPUSH, B) /* ary_push(R(a),R(a+1)) */ OPCODE(ARYPUSH, BB) /* ary_push(R(a),R(a+1)..R(a+b)) */
OPCODE(ARYPUSH_N, BB) /* ary_push(R(a),R(a+1)..R(a+b)) */
OPCODE(ARYDUP, B) /* R(a) = ary_dup(R(a)) */ OPCODE(ARYDUP, B) /* R(a) = ary_dup(R(a)) */
OPCODE(AREF, BBB) /* R(a) = R(b)[c] */ OPCODE(AREF, BBB) /* R(a) = R(b)[c] */
OPCODE(ASET, BBB) /* R(a)[c] = R(b) */ OPCODE(ASET, BBB) /* R(a)[c] = R(b) */
......
...@@ -1483,15 +1483,17 @@ attrsym(codegen_scope *s, mrb_sym a) ...@@ -1483,15 +1483,17 @@ attrsym(codegen_scope *s, mrb_sym a)
} }
#define CALL_MAXARGS 127 #define CALL_MAXARGS 127
#define GEN_LIT_ARY_MAX 255 #define GEN_LIT_ARY_MAX 64
static int static int
gen_values(codegen_scope *s, node *t, int val, int extra, int limit) gen_values(codegen_scope *s, node *t, int val, int extra, int limit)
{ {
int n = 0; int n = 0;
int first = 1; int first = 1;
int slimit = GEN_LIT_ARY_MAX;
if (limit == 0) limit = GEN_LIT_ARY_MAX; if (limit == 0) limit = GEN_LIT_ARY_MAX;
if (cursp() >= slimit) slimit = INT16_MAX;
if (!val) { if (!val) {
while (t) { while (t) {
...@@ -1505,7 +1507,7 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit) ...@@ -1505,7 +1507,7 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit)
while (t) { while (t) {
int is_splat = nint(t->car->car) == NODE_SPLAT; int is_splat = nint(t->car->car) == NODE_SPLAT;
if (is_splat || n+extra >= limit-1) { /* flush stack */ if (is_splat || n+extra >= limit-1 || cursp() >= slimit) { /* flush stack */
pop_n(n); pop_n(n);
if (first) { if (first) {
if (n == 0) { if (n == 0) {
...@@ -1516,14 +1518,11 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit) ...@@ -1516,14 +1518,11 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit)
} }
push(); push();
first = 0; first = 0;
limit = GEN_LIT_ARY_MAX;
} }
else if (n > 0) { else if (n > 0) {
if (n == 1) { pop();
genop_1(s, OP_ARYPUSH, cursp()); genop_2(s, OP_ARYPUSH, cursp(), n);
}
else {
genop_2(s, OP_ARYPUSH_N, cursp(), n);
}
push(); push();
} }
n = 0; n = 0;
...@@ -1543,12 +1542,7 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit) ...@@ -1543,12 +1542,7 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit)
pop(); pop();
if (n > 0) { if (n > 0) {
pop_n(n); pop_n(n);
if (n == 1) { genop_2(s, OP_ARYPUSH, cursp(), n);
genop_1(s, OP_ARYPUSH, cursp());
}
else {
genop_2(s, OP_ARYPUSH_N, cursp(), n);
}
} }
return -1; /* variable length */ return -1; /* variable length */
} }
...@@ -1570,7 +1564,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) ...@@ -1570,7 +1564,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
} }
tree = tree->cdr->cdr->car; tree = tree->cdr->cdr->car;
if (tree) { if (tree) {
n = gen_values(s, tree->car, VAL, sp?1:0, CALL_MAXARGS); n = gen_values(s, tree->car, VAL, sp?1:0, 14);
if (n < 0) { if (n < 0) {
n = noop = sendv = 1; n = noop = sendv = 1;
push(); push();
...@@ -1580,7 +1574,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) ...@@ -1580,7 +1574,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
if (sendv) { if (sendv) {
gen_move(s, cursp(), sp, 0); gen_move(s, cursp(), sp, 0);
pop(); pop();
genop_1(s, OP_ARYPUSH, cursp()); genop_2(s, OP_ARYPUSH, cursp(), 1);
push(); push();
} }
else { else {
...@@ -1825,7 +1819,7 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) ...@@ -1825,7 +1819,7 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val)
pop_n(i); pop_n(i);
if (gen) { if (gen) {
pop(); pop();
genop_2(s, OP_ARYPUSH_N, cursp(), i); genop_2(s, OP_ARYPUSH, cursp(), i);
} }
else { else {
genop_2(s, OP_ARRAY, cursp(), i); genop_2(s, OP_ARRAY, cursp(), i);
...@@ -1844,7 +1838,7 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) ...@@ -1844,7 +1838,7 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val)
pop_n(i); pop_n(i);
if (gen) { if (gen) {
pop(); pop();
genop_2(s, OP_ARYPUSH_N, cursp(), i); genop_2(s, OP_ARYPUSH, cursp(), i);
} }
else { else {
genop_2(s, OP_ARRAY, cursp(), i); genop_2(s, OP_ARRAY, cursp(), i);
...@@ -2404,7 +2398,9 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2404,7 +2398,9 @@ codegen(codegen_scope *s, node *tree, int val)
{ {
int len = 0; int len = 0;
mrb_bool update = FALSE; mrb_bool update = FALSE;
int slimit = GEN_LIT_ARY_MAX;
if (cursp() >= GEN_LIT_ARY_MAX) slimit = INT16_MAX;
while (tree) { while (tree) {
if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) { if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) {
if (len > 0) { if (len > 0) {
...@@ -2433,7 +2429,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2433,7 +2429,7 @@ codegen(codegen_scope *s, node *tree, int val)
len++; len++;
} }
tree = tree->cdr; tree = tree->cdr;
if (val && cursp() > 127) { if (val && cursp() >= slimit) {
pop_n(len*2); pop_n(len*2);
if (!update) { if (!update) {
genop_2(s, OP_HASH, cursp(), len); genop_2(s, OP_HASH, cursp(), len);
...@@ -2593,7 +2589,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2593,7 +2589,7 @@ codegen(codegen_scope *s, node *tree, int val)
idx = new_sym(s, nsym(n->cdr->car)); idx = new_sym(s, nsym(n->cdr->car));
base = cursp()-1; base = cursp()-1;
if (n->cdr->cdr->car) { if (n->cdr->cdr->car) {
nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1, CALL_MAXARGS); nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1, 14);
if (nargs >= 0) { if (nargs >= 0) {
callargs = nargs; callargs = nargs;
} }
...@@ -2638,7 +2634,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2638,7 +2634,7 @@ codegen(codegen_scope *s, node *tree, int val)
if (nint(tree->car->car) == NODE_CALL) { if (nint(tree->car->car) == NODE_CALL) {
if (callargs == CALL_MAXARGS) { if (callargs == CALL_MAXARGS) {
pop(); pop();
genop_1(s, OP_ARYPUSH, cursp()); genop_2(s, OP_ARYPUSH, cursp(), 1);
} }
else { else {
pop_n(callargs); pop_n(callargs);
...@@ -2695,7 +2691,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2695,7 +2691,7 @@ codegen(codegen_scope *s, node *tree, int val)
} }
if (callargs == CALL_MAXARGS) { if (callargs == CALL_MAXARGS) {
pop(); pop();
genop_1(s, OP_ARYPUSH, cursp()); genop_2(s, OP_ARYPUSH, cursp(), 1);
} }
else { else {
pop_n(callargs); pop_n(callargs);
...@@ -2726,7 +2722,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2726,7 +2722,7 @@ codegen(codegen_scope *s, node *tree, int val)
if (tree) { if (tree) {
node *args = tree->car; node *args = tree->car;
if (args) { if (args) {
n = gen_values(s, args, VAL, 0, CALL_MAXARGS); n = gen_values(s, args, VAL, 0, 14);
if (n < 0) { if (n < 0) {
n = noop = sendv = 1; n = noop = sendv = 1;
push(); push();
...@@ -2807,7 +2803,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2807,7 +2803,7 @@ codegen(codegen_scope *s, node *tree, int val)
if (ainfo < 0) codegen_error(s, "invalid yield (SyntaxError)"); if (ainfo < 0) codegen_error(s, "invalid yield (SyntaxError)");
push(); push();
if (tree) { if (tree) {
n = gen_values(s, tree, VAL, 0, CALL_MAXARGS); n = gen_values(s, tree, VAL, 0, 14);
if (n < 0) { if (n < 0) {
n = sendv = 1; n = sendv = 1;
push(); push();
......
...@@ -431,12 +431,8 @@ codedump(mrb_state *mrb, const mrb_irep *irep) ...@@ -431,12 +431,8 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
printf("OP_ARYCAT\tR%d\tR%d\t", a, a+1); printf("OP_ARYCAT\tR%d\tR%d\t", a, a+1);
print_lv_a(mrb, irep, a); print_lv_a(mrb, irep, a);
break; break;
CASE(OP_ARYPUSH, B): CASE(OP_ARYPUSH, BB):
printf("OP_ARYPUSH\tR%d\t", a); printf("OP_ARYPUSH\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a);
break;
CASE(OP_ARYPUSH_N, BB):
printf("OP_ARYPUSH_N\tR%d\t%d\t", a, b);
print_lv_a(mrb, irep, a); print_lv_a(mrb, irep, a);
break; break;
CASE(OP_ARYDUP, B): CASE(OP_ARYDUP, B):
......
...@@ -2546,12 +2546,7 @@ RETRY_TRY_BLOCK: ...@@ -2546,12 +2546,7 @@ RETRY_TRY_BLOCK:
NEXT; NEXT;
} }
CASE(OP_ARYPUSH, B) { CASE(OP_ARYPUSH, BB) {
mrb_ary_push(mrb, regs[a], regs[a+1]);
NEXT;
}
CASE(OP_ARYPUSH_N, BB) {
for (mrb_int i=0; i<b; i++) { for (mrb_int i=0; i<b; i++) {
mrb_ary_push(mrb, regs[a], regs[a+i+1]); mrb_ary_push(mrb, regs[a], regs[a+i+1]);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment