summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2019-09-07 16:01:16 +0900
committerYusuke Endoh <mame@ruby-lang.org>2019-09-07 16:05:15 +0900
commit1e008105bc4576af46036f1c73f96f7f93bee319 (patch)
tree52bb069d7af5ca839e659e10b3e577ab6b01fe4e /compile.c
parentc725a4e48fc30cb60e539e86c917698209184345 (diff)
compile.c (compile_list): emit newarraykwsplat only at the last chunk
`[{}, {}, {}, ..., {}, *{}]` is wrongly created. A big array literal is created and concatenated for every 256 elements. The newarraykwsplat must be emitted only at the last chunk.
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c11
1 files changed, 3 insertions, 8 deletions
diff --git a/compile.c b/compile.c
index ed9deea976..43a103842a 100644
--- a/compile.c
+++ b/compile.c
@@ -3944,13 +3944,13 @@ compile_list(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_roo
int num_kw = 0;
while (node) {
- const NODE *start_node = node, *end_node;
+ const NODE *start_node = node, *end_node, *prev_node;
const NODE *kw = 0;
const int max = 0x100;
DECL_ANCHOR(anchor);
INIT_ANCHOR(anchor);
- for (i=0; i<max && node; i++, len++, node = node->nd_next) {
+ for (i=0; i<max && node; i++, len++, prev_node = node, node = node->nd_next) {
if (CPDEBUG > 0) {
EXPECT_NODE("compile_list", node, NODE_LIST, -1);
}
@@ -4032,14 +4032,9 @@ compile_list(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_roo
if (!popped || kw) {
switch (type) {
case COMPILE_ARRAY_TYPE_ARRAY: {
- const NODE *check_node = node_root;
-
/* Find last node in array, and if it is a keyword argument, then set
flag to check and remove empty keyword arguments hash from array */
- while(check_node->nd_next) {
- check_node = check_node->nd_next;
- }
- if (nd_type(check_node->nd_head) == NODE_HASH && check_node->nd_head->nd_brace == 0) {
+ if (!node && nd_type(prev_node->nd_head) == NODE_HASH && prev_node->nd_head->nd_brace == 0) {
ADD_INSN1(anchor, line, newarraykwsplat, INT2FIX(i));
}
else {