summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2019-09-07 16:26:38 +0900
committerYusuke Endoh <mame@ruby-lang.org>2019-09-07 16:26:38 +0900
commit2f2f8107d0d21f5ebaaaf3b2d7ed6d09dfec91d5 (patch)
treea53407c61568d3b38d3fc0f3feb50ba0621cf0d6 /compile.c
parent1e008105bc4576af46036f1c73f96f7f93bee319 (diff)
downloadruby-2f2f8107d0d21f5ebaaaf3b2d7ed6d09dfec91d5.tar.gz
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].
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/compile.c b/compile.c
index 43a103842a..10dff7ca03 100644
--- a/compile.c
+++ b/compile.c
@@ -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);