[前][次][番号順一覧][スレッド一覧]

ruby-changes:57643

From: Yusuke <ko1@a...>
Date: Sat, 7 Sep 2019 16:51:49 +0900 (JST)
Subject: [ruby-changes:57643] a2260bd636 (master): compile.c: Separate compile_list to two functions for Array and Hash

https://git.ruby-lang.org/ruby.git/commit/?id=a2260bd636

From a2260bd636646cde486afeebe5a0a7ef5ec78a4e Mon Sep 17 00:00:00 2001
From: Yusuke Endoh <mame@r...>
Date: Sat, 7 Sep 2019 16:45:49 +0900
Subject: compile.c: Separate compile_list to two functions for Array and Hash

compile_list was for the compilation of Array literal and Hash literal.
I guess it was originally reasonable to handle them in one function, but
now, compilation of Array is very different from Hash.  So the function
was complicated by many branches for Array and Hash.

This change separates the function to two ones for Array and Hash.

diff --git a/compile.c b/compile.c
index 10dff7c..c2fbab0 100644
--- a/compile.c
+++ b/compile.c
@@ -3849,10 +3849,9 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, https://github.com/ruby/ruby/blob/trunk/compile.c#L3849
 }
 
 static int
-compile_args(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_root,
+compile_args(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node,
                    struct rb_call_info_kw_arg **keywords_ptr, unsigned int *flag)
 {
-    const NODE *node = node_root;
     int len = 0;
 
     for (; node; len++, node = node->nd_next) {
@@ -3872,11 +3871,6 @@ compile_args(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_roo https://github.com/ruby/ruby/blob/trunk/compile.c#L3871
     return len;
 }
 
-enum compile_list_type_t {
-    COMPILE_ARRAY_TYPE_ARRAY,
-    COMPILE_ARRAY_TYPE_HASH,
-};
-
 static inline int
 static_literal_node_p(const NODE *node, const rb_iseq_t *iseq)
 {
@@ -3922,21 +3916,111 @@ static_literal_value(const NODE *node, rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/compile.c#L3916
 }
 
 static int
-compile_list(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_root,
-              enum compile_list_type_t type, int popped)
+compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped)
 {
-    const NODE *node = node_root;
     int line = (int)nd_line(node);
     int len = 0;
 
     if (nd_type(node) == NODE_ZLIST) {
 	if (!popped) {
-	    switch (type) {
-	      case COMPILE_ARRAY_TYPE_ARRAY: ADD_INSN1(ret, line, newarray, INT2FIX(0)); break;
-	      case COMPILE_ARRAY_TYPE_HASH: ADD_INSN1(ret, line, newhash, INT2FIX(0)); break;
+	    ADD_INSN1(ret, line, newarray, INT2FIX(0));
+	}
+    }
+    else {
+	int opt_p = 1;
+	int first = 1, i;
+
+	while (node) {
+	    const NODE *start_node = node, *end_node, *prev_node;
+	    const int max = 0x100;
+	    DECL_ANCHOR(anchor);
+	    INIT_ANCHOR(anchor);
+
+	    for (i=0; i<max && node; i++, len++, prev_node = node, node = node->nd_next) {
+		if (CPDEBUG > 0) {
+		    EXPECT_NODE("compile_array", node, NODE_LIST, -1);
+		}
+
+                if (opt_p && !static_literal_node_p(node, iseq)) {
+		    opt_p = 0;
+		}
+
+                NO_CHECK(COMPILE_(anchor, "array element", node->nd_head, popped));
+	    }
+
+            if (opt_p) {
+		if (!popped) {
+		    VALUE ary = rb_ary_tmp_new(i);
+
+		    end_node = node;
+		    node = start_node;
+
+		    while (node != end_node) {
+                        rb_ary_push(ary, static_literal_value(node, iseq));
+			node = node->nd_next;
+		    }
+                    while (node && static_literal_node_p(node, iseq)) {
+                        rb_ary_push(ary, static_literal_value(node, iseq));
+                        node = node->nd_next;
+                        len++;
+                    }
+
+		    OBJ_FREEZE(ary);
+
+		    iseq_add_mark_object_compile_time(iseq, ary);
+
+		    if (first) {
+			first = 0;
+                        ADD_INSN1(ret, line, duparray, ary);
+		    }
+		    else {
+                        ADD_INSN1(ret, line, putobject, ary);
+                        ADD_INSN(ret, line, concatarray);
+		    }
+		}
+	    }
+	    else {
+		if (!popped) {
+                    /* 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 */
+                    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 {
+                        ADD_INSN1(anchor, line, newarray, INT2FIX(i));
+                    }
+
+
+                    if (first) {
+                        first = 0;
+                    }
+                    else {
+                        ADD_INSN(anchor, line, concatarray);
+                    }
+
+                    APPEND_LIST(ret, anchor);
+		}
+		else {
+		    /* popped */
+		    APPEND_LIST(ret, anchor);
+		}
 	    }
 	}
     }
+    return len;
+}
+
+static int
+compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped)
+{
+    int line = (int)nd_line(node);
+    int len = 0;
+
+    if (nd_type(node) == NODE_ZLIST) {
+	if (!popped) {
+	    ADD_INSN1(ret, line, newhash, INT2FIX(0));
+	}
+    }
     else {
 	int opt_p = 1;
 	int first = 1, i;
@@ -3944,18 +4028,18 @@ compile_list(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_roo https://github.com/ruby/ruby/blob/trunk/compile.c#L4028
         int num_kw = 0;
 
 	while (node) {
-	    const NODE *start_node = node, *end_node, *prev_node;
+	    const NODE *start_node = node, *end_node;
 	    const NODE *kw = 0;
 	    const int max = 0x100;
 	    DECL_ANCHOR(anchor);
 	    INIT_ANCHOR(anchor);
 
-	    for (i=0; i<max && node; i++, len++, prev_node = node, node = node->nd_next) {
+	    for (i=0; i<max && node; i++, len++, node = node->nd_next) {
 		if (CPDEBUG > 0) {
-		    EXPECT_NODE("compile_list", node, NODE_LIST, -1);
+		    EXPECT_NODE("compile_hash", node, NODE_LIST, -1);
 		}
 
-                if (type == COMPILE_ARRAY_TYPE_HASH && !node->nd_head) {
+                if (!node->nd_head) {
 		    kw = node->nd_next;
                     num_kw++;
 		    node = 0;
@@ -3987,24 +4071,15 @@ compile_list(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_roo https://github.com/ruby/ruby/blob/trunk/compile.c#L4071
                         rb_ary_push(ary, static_literal_value(node, iseq));
 			node = node->nd_next;
 		    }
-                    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++;
-                        }
+                    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);
@@ -4013,103 +4088,67 @@ compile_list(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_roo https://github.com/ruby/ruby/blob/trunk/compile.c#L4088
 
 		    if (first) {
 			first = 0;
-			if (type == COMPILE_ARRAY_TYPE_ARRAY) {
-			    ADD_INSN1(ret, line, duparray, ary);
-			}
-			else { /* COMPILE_ARRAY_TYPE_HASH */
-                            VALUE hash;
+                        VALUE hash;
 
-                            hash = rb_hash_new_with_size(RARRAY_LEN(ary) / 2);
-                            rb_hash_bulk_insert(RARRAY_LEN(ary), RARRAY_CONST_PTR_TRANSIENT(ary), hash);
-                            iseq_add_mark_object_compile_time(iseq, rb_obj_hide(hash));
-                            ADD_INSN1(ret, line, duphash, hash);
-			}
+                        hash = rb_hash_new_with_size(RARRAY_LEN(ary) / 2);
+                        rb_hash_bulk_insert(RARRAY_LEN(ary), RARRAY_CONST_PTR_TRANSIENT(ary), hash);
+                        iseq_add_mark_object_compile_time(iseq, rb_obj_hide(hash));
+                        ADD_INSN1(ret, line, duphash, hash);
 		    }
 		    else {
-			if (type == COMPILE_ARRAY_TYPE_ARRAY) {
-			    ADD_INSN1(ret, line, putobject, ary);
-			    ADD_INSN(ret, line, concatarray);
-			}
-			else {
-			    COMPILE_ERROR(ERROR_ARGS "core#hash_merge_ary");
-			    return -1;
-			}
+                        COMPILE_ERROR(ERROR_ARGS "core#hash_merge_ary");
+                        return -1;
 		    }
 		}
 	    }
 	    else {
-		if (!popped || kw) {
-		    switch (type) {
-                      case COMPILE_ARRAY_TYPE_ARRAY: {
-                        /* 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 */
-                        if (!node && nd_type(prev_node->nd_head) == NODE_HASH && prev_node->nd_head->nd_brace == 0) {
-                            ADD_INSN1(anchor, line, newarraykwsplat, INT2FIX(i));
+                if (!popped || kw) {
+                    if (i > 0) {
+                        num_kw++;
+                        if (first) {
+                            if (!popped) {
+                                ADD_INSN1(anchor, line, new (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]