compile.c (compile_list): allow an odd-length hidden array literal

An array literal [1,2,...,301] was compiled to the following iseq:

  duparray [1,2,...,300]
  putobject [301]
  concatarray

The Array literal optimization took every two elements maybe because it
must handle not only Array but also Hash.
Now the optimization takes each element if it is an Array literal.  So
the new iseq is: duparray [1,2,...,301].
This commit is contained in:
Yusuke Endoh 2019-09-07 16:26:38 +09:00
Родитель 1e008105bc
Коммит 2f2f8107d0
1 изменённых файлов: 19 добавлений и 10 удалений

Просмотреть файл

@ -3987,16 +3987,25 @@ compile_list(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_roo
rb_ary_push(ary, static_literal_value(node, iseq));
node = node->nd_next;
}
while (node && node->nd_next &&
static_literal_node_p(node, iseq) &&
static_literal_node_p(node->nd_next, iseq)) {
VALUE elem[2];
elem[0] = static_literal_value(node, iseq);
elem[1] = static_literal_value(node->nd_next, iseq);
rb_ary_cat(ary, elem, 2);
node = node->nd_next->nd_next;
len++;
}
if (type == COMPILE_ARRAY_TYPE_ARRAY) {
while (node && static_literal_node_p(node, iseq)) {
rb_ary_push(ary, static_literal_value(node, iseq));
node = node->nd_next;
len++;
}
}
else { /* COMPILE_ARRAY_TYPE_HASH */
while (node && node->nd_next &&
static_literal_node_p(node, iseq) &&
static_literal_node_p(node->nd_next, iseq)) {
VALUE elem[2];
elem[0] = static_literal_value(node, iseq);
elem[1] = static_literal_value(node->nd_next, iseq);
rb_ary_cat(ary, elem, 2);
node = node->nd_next->nd_next;
len++;
}
}
OBJ_FREEZE(ary);