From 2f2f8107d0d21f5ebaaaf3b2d7ed6d09dfec91d5 Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Sat, 7 Sep 2019 16:26:38 +0900 Subject: [PATCH] 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]. --- compile.c | 29 +++++++++++++++++++---------- 1 file 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);