compile.c: move expansion of massign
* compile.c (iseq_compile_each): move expansion for massign to variable of for-loop from the parser, to reduce method calls on intermediate objects. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50398 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
69ba9302c5
commit
810522e0ff
30
compile.c
30
compile.c
@ -3624,8 +3624,34 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
iseq->compile_data->ensure_node_stack = iseq->compile_data->ensure_node_stack->prev;
|
iseq->compile_data->ensure_node_stack = iseq->compile_data->ensure_node_stack->prev;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_ITER:
|
case NODE_FOR:
|
||||||
case NODE_FOR:{
|
if (node->nd_var) {
|
||||||
|
/* massign to var in "for"
|
||||||
|
* args.length == 1 && Array === (tmp = args[0]) ? tmp : args
|
||||||
|
*/
|
||||||
|
NODE *var = node->nd_var;
|
||||||
|
LABEL *not_single = NEW_LABEL(nd_line(var));
|
||||||
|
LABEL *not_ary = NEW_LABEL(nd_line(var));
|
||||||
|
COMPILE(ret, "for var", var);
|
||||||
|
ADD_INSN(ret, line, dup);
|
||||||
|
ADD_CALL(ret, line, idLength, INT2FIX(0));
|
||||||
|
ADD_INSN1(ret, line, putobject, INT2FIX(1));
|
||||||
|
ADD_CALL(ret, line, idEq, INT2FIX(1));
|
||||||
|
ADD_INSNL(ret, line, branchunless, not_single);
|
||||||
|
ADD_INSN(ret, line, dup);
|
||||||
|
ADD_INSN1(ret, line, putobject, INT2FIX(0));
|
||||||
|
ADD_CALL(ret, line, idAREF, INT2FIX(1));
|
||||||
|
ADD_INSN1(ret, line, putobject, rb_cArray);
|
||||||
|
ADD_INSN1(ret, line, topn, INT2FIX(1));
|
||||||
|
ADD_CALL(ret, line, idEqq, INT2FIX(1));
|
||||||
|
ADD_INSNL(ret, line, branchunless, not_ary);
|
||||||
|
ADD_INSN(ret, line, swap);
|
||||||
|
ADD_LABEL(ret, not_ary);
|
||||||
|
ADD_INSN(ret, line, pop);
|
||||||
|
ADD_LABEL(ret, not_single);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NODE_ITER:{
|
||||||
VALUE prevblock = iseq->compile_data->current_block;
|
VALUE prevblock = iseq->compile_data->current_block;
|
||||||
LABEL *retry_label = NEW_LABEL(line);
|
LABEL *retry_label = NEW_LABEL(line);
|
||||||
LABEL *retry_end_l = NEW_LABEL(line);
|
LABEL *retry_end_l = NEW_LABEL(line);
|
||||||
|
20
parse.y
20
parse.y
@ -2909,25 +2909,7 @@ primary : literal
|
|||||||
NODE *args, *scope;
|
NODE *args, *scope;
|
||||||
|
|
||||||
if (nd_type($2) == NODE_MASGN) {
|
if (nd_type($2) == NODE_MASGN) {
|
||||||
/* if args.length == 1 && args[0].kind_of?(Array)
|
m->nd_next = node_assign($2, NEW_FOR(NEW_DVAR(id), 0, 0));
|
||||||
* args = args[0]
|
|
||||||
* end
|
|
||||||
*/
|
|
||||||
NODE *one = NEW_LIST(NEW_LIT(INT2FIX(1)));
|
|
||||||
NODE *zero = NEW_LIST(NEW_LIT(INT2FIX(0)));
|
|
||||||
m->nd_next = block_append(
|
|
||||||
NEW_IF(
|
|
||||||
NEW_NODE(NODE_AND,
|
|
||||||
NEW_CALL(NEW_CALL(NEW_DVAR(id), idLength, 0),
|
|
||||||
idEq, one),
|
|
||||||
NEW_CALL(NEW_CALL(NEW_DVAR(id), idAREF, zero),
|
|
||||||
rb_intern("kind_of?"), NEW_LIST(NEW_LIT(rb_cArray))),
|
|
||||||
0),
|
|
||||||
NEW_DASGN_CURR(id,
|
|
||||||
NEW_CALL(NEW_DVAR(id), idAREF, zero)),
|
|
||||||
0),
|
|
||||||
node_assign($2, NEW_DVAR(id)));
|
|
||||||
|
|
||||||
args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
|
args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user