diff options
author | Yusuke Endoh <mame@ruby-lang.org> | 2019-09-07 16:26:38 +0900 |
---|---|---|
committer | Yusuke Endoh <mame@ruby-lang.org> | 2019-09-07 16:26:38 +0900 |
commit | 2f2f8107d0d21f5ebaaaf3b2d7ed6d09dfec91d5 (patch) | |
tree | a53407c61568d3b38d3fc0f3feb50ba0621cf0d6 /compile.c | |
parent | 1e008105bc4576af46036f1c73f96f7f93bee319 (diff) | |
download | ruby-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.c | 29 |
1 files changed, 19 insertions, 10 deletions
@@ -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); |