From afb10c62c2e45801df4245e6131af3a98efdebd1 Mon Sep 17 00:00:00 2001 From: mame Date: Mon, 26 Dec 2011 14:19:58 +0000 Subject: [PATCH] * node.h, parse.y (new_args_gen), compile.c (iseq_set_arguments): use struct rb_args_info instead of NODEs. This is a preparation for keyword argument (see [ruby-core:40290]). * node.c (dump_node), gc.c (gc_mark_children, obj_free): bookkeeping. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34134 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 8 ++++++++ compile.c | 58 ++++++++++++++++++------------------------------------- gc.c | 18 ++++++++++++++++- node.c | 53 ++++++++------------------------------------------ node.h | 17 +++++++++++++++- parse.y | 31 ++++++++++++++--------------- 6 files changed, 83 insertions(+), 102 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5719c3f4dfc351..e4e6561b34d11f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Mon Dec 26 21:03:18 2011 Yusuke Endoh + + * node.h, parse.y (new_args_gen), compile.c (iseq_set_arguments): use + struct rb_args_info instead of NODEs. + This is a preparation for keyword argument (see [ruby-core:40290]). + + * node.c (dump_node), gc.c (gc_mark_children, obj_free): bookkeeping. + Mon Dec 26 20:59:51 2011 Yusuke Endoh * node.h, parse.y (lambda, f_larglist): remove NEW_LAMBDA hack. diff --git a/compile.c b/compile.c index 9f7e7b5e8df647..38139f110b1743 100644 --- a/compile.c +++ b/compile.c @@ -1068,52 +1068,34 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args) debugs("iseq_set_arguments: %s\n", node_args ? "" : "0"); if (node_args) { - NODE *node_aux = node_args->nd_next; - NODE *node_opt = node_args->nd_opt; + struct rb_args_info *args = node_args->nd_ainfo; ID rest_id = 0; int last_comma = 0; ID block_id = 0; - NODE *node_init = 0; if (nd_type(node_args) != NODE_ARGS) { rb_bug("iseq_set_arguments: NODE_ARGS is expected, but %s", ruby_node_name(nd_type(node_args))); } - /* - * new argument information: - * NODE_ARGS [m: int, o: NODE_OPT_ARG, ->] - * NODE_ARGS_AUX [r: ID, b: ID, ->] - * NODE_ARGS_AUX [Pst: id, Plen: int, init: NODE*] - * optarg information: - * NODE_OPT_ARGS [idx, expr, next ->] - * init arg: - * NODE_AND(m_init, p_init) - * if "r" is 1, it's means "{|x,|}" type block parameter. - */ - iseq->argc = (int)node_args->nd_frml; + iseq->argc = (int)args->pre_args_num; debugs(" - argc: %d\n", iseq->argc); - if (node_aux) { - rest_id = node_aux->nd_rest; - if (rest_id == 1) { - last_comma = 1; - rest_id = 0; - } - block_id = (ID)node_aux->nd_body; - node_aux = node_aux->nd_next; - - if (node_aux) { - ID post_start_id = node_aux->nd_pid; - iseq->arg_post_start = get_dyna_var_idx_at_raw(iseq, post_start_id); - iseq->arg_post_len = (int)node_aux->nd_plen; - node_init = node_aux->nd_next; - } + rest_id = args->rest_arg; + if (rest_id == 1) { + last_comma = 1; + rest_id = 0; } + block_id = args->block_arg; - if (node_opt) { - NODE *node = node_opt; + if (args->first_post_arg) { + iseq->arg_post_start = get_dyna_var_idx_at_raw(iseq, args->first_post_arg); + iseq->arg_post_len = args->post_args_num; + } + + if (args->opt_args) { + NODE *node = args->opt_args; LABEL *label; VALUE labels = rb_ary_tmp_new(1); int i = 0, j; @@ -1145,13 +1127,11 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args) iseq->arg_opts = 0; } - if (node_init) { - if (node_init->nd_1st) { /* m_init */ - COMPILE_POPED(optargs, "init arguments (m)", node_init->nd_1st); - } - if (node_init->nd_2nd) { /* p_init */ - COMPILE_POPED(optargs, "init arguments (p)", node_init->nd_2nd); - } + if (args->pre_init) { /* m_init */ + COMPILE_POPED(optargs, "init arguments (m)", args->pre_init); + } + if (args->post_init) { /* p_init */ + COMPILE_POPED(optargs, "init arguments (p)", args->post_init); } if (rest_id) { diff --git a/gc.c b/gc.c index ada704703596ed..ae2f0c2910fb6d 100644 --- a/gc.c +++ b/gc.c @@ -1720,7 +1720,6 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev) case NODE_CALL: case NODE_DEFS: case NODE_OP_ASGN1: - case NODE_ARGS: gc_mark(objspace, (VALUE)obj->as.node.u1.node, lev); /* fall through */ case NODE_SUPER: /* 3 */ @@ -1788,6 +1787,18 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev) ptr = (VALUE)obj->as.node.u2.node; goto again; + case NODE_ARGS: /* custom */ + { + struct rb_args_info *args = obj->as.node.u3.args; + if (args) { + if (args->pre_init) gc_mark(objspace, (VALUE)args->pre_init, lev); + if (args->post_init) gc_mark(objspace, (VALUE)args->post_init, lev); + if (args->opt_args) gc_mark(objspace, (VALUE)args->opt_args, lev); + } + } + ptr = (VALUE)obj->as.node.u2.node; + goto again; + case NODE_ZARRAY: /* - */ case NODE_ZSUPER: case NODE_VCALL: @@ -2381,6 +2392,11 @@ obj_free(rb_objspace_t *objspace, VALUE obj) xfree(RANY(obj)->as.node.u1.tbl); } break; + case NODE_ARGS: + if (RANY(obj)->as.node.u3.args) { + xfree(RANY(obj)->as.node.u3.args); + } + break; case NODE_ALLOCA: xfree(RANY(obj)->as.node.u1.node); break; diff --git a/node.c b/node.c index 5912bc475262d9..eca8981bfc9416 100644 --- a/node.c +++ b/node.c @@ -837,55 +837,18 @@ dump_node(VALUE buf, VALUE indent, int comment, NODE *node) F_NODE(nd_2nd, "post arguments"); break; - case NODE_ARGS_AUX: - ANN("method parameters (cont'd)"); - F_CUSTOM1(nd_rest, "rest argument", { - if (node->nd_rest == 1) A("nil (with last comma)"); - else A_ID(node->nd_rest); - }); - F_CUSTOM1(nd_body, "block argument", { A_ID((ID)node->nd_body); }); - LAST_NODE; - F_CUSTOM2(nd_next, "aux info 2", { - node = node->nd_next; - next_indent = "| "; - if (!node) { - D_NULL_NODE; - } - else { - D_NODE_HEADER(node); - ANN("method parameters (cont'd)"); - F_ID(nd_pid, "first post argument"); - F_LONG(nd_plen, "post argument length"); - LAST_NODE; - F_CUSTOM2(nd_next, "aux info 3", { - node = node->nd_next; - next_indent = "| "; - if (!node) { - D_NULL_NODE; - } - else { - D_NODE_HEADER(node); - ANN("method parameters (cont'd)"); - ANN("\"init arguments (m)\" evaluates multiple assignments before rest argument"); - ANN("\"init arguments (p)\" evaluates multiple assignments after rest argument"); - ANN("example: def foo((m1, m2), *r, (p1, p2))"); - F_NODE(nd_1st, "init arguments (m)"); - LAST_NODE; - F_NODE(nd_2nd, "init arguments (p)"); - } - }); - } - }); - break; - case NODE_ARGS: ANN("method parameters"); ANN("format: def method_name(.., [nd_opt=some], *[nd_rest], [nd_pid], .., &[nd_body])"); ANN("example: def foo(a, b, opt1=1, opt2=2, *rest, y, z, &blk); end"); - F_LONG(nd_frml, "argc"); - F_NODE(nd_next, "aux info 1"); - LAST_NODE; - F_NODE(nd_opt, "optional arguments"); + F_LONG(nd_ainfo->pre_args_num, "count of mandatory (pre-)arguments"); + F_NODE(nd_ainfo->pre_init, "initialization of (pre-)arguments"); + F_LONG(nd_ainfo->post_args_num, "count of mandatory post-arguments"); + F_NODE(nd_ainfo->post_init, "initialization of post-arguments"); + F_ID(nd_ainfo->first_post_arg, "first post argument"); + F_ID(nd_ainfo->rest_arg, "rest argument"); + F_ID(nd_ainfo->block_arg, "block argument"); + F_NODE(nd_ainfo->opt_args, "optional arguments"); break; case NODE_SCOPE: diff --git a/node.h b/node.h index 7c360cd6a94522..873c52cc3a9bba 100644 --- a/node.h +++ b/node.h @@ -253,6 +253,7 @@ typedef struct RNode { ID id; long state; struct rb_global_entry *entry; + struct rb_args_info *args; long cnt; VALUE value; } u3; @@ -321,6 +322,7 @@ typedef struct RNode { #define nd_recv u1.node #define nd_mid u2.id #define nd_args u3.node +#define nd_ainfo u3.args #define nd_noex u3.id #define nd_defn u3.node @@ -415,7 +417,6 @@ typedef struct RNode { #define NEW_VCALL(m) NEW_NODE(NODE_VCALL,0,m,0) #define NEW_SUPER(a) NEW_NODE(NODE_SUPER,0,0,a) #define NEW_ZSUPER() NEW_NODE(NODE_ZSUPER,0,0,0) -#define NEW_ARGS(m,o) NEW_NODE(NODE_ARGS,o,m,0) #define NEW_ARGS_AUX(r,b) NEW_NODE(NODE_ARGS_AUX,r,b,0) #define NEW_OPT_ARG(i,v) NEW_NODE(NODE_OPT_ARG,i,v,0) #define NEW_POSTARG(i,v) NEW_NODE(NODE_POSTARG,i,v,0) @@ -483,6 +484,20 @@ VALUE rb_gvar_set(struct rb_global_entry *, VALUE); VALUE rb_gvar_defined(struct rb_global_entry *); const struct kwtable *rb_reserved_word(const char *, unsigned int); +struct rb_args_info { + long pre_args_num; /* count of mandatory pre-arguments */ + NODE *pre_init; + + long post_args_num; /* count of mandatory post-arguments */ + NODE *post_init; + ID first_post_arg; + + ID rest_arg; + ID block_arg; + + NODE *opt_args; +}; + struct parser_params; void *rb_parser_malloc(struct parser_params *, size_t); void *rb_parser_realloc(struct parser_params *, void *, size_t); diff --git a/parse.y b/parse.y index ace81f9f192b38..b186ed9f38fb26 100644 --- a/parse.y +++ b/parse.y @@ -9121,25 +9121,24 @@ static NODE* new_args_gen(struct parser_params *parser, NODE *m, NODE *o, ID r, NODE *p, ID b) { int saved_line = ruby_sourceline; - NODE *node; - NODE *i1, *i2 = 0; + struct rb_args_info *args; - node = NEW_ARGS(m ? m->nd_plen : 0, o); - i1 = m ? m->nd_next : 0; - node->nd_next = NEW_ARGS_AUX(r, b); + args = ALLOC(struct rb_args_info); + + args->pre_args_num = m ? m->nd_plen : 0; + args->pre_init = m ? m->nd_next : 0; + + args->post_args_num = p ? p->nd_plen : 0; + args->post_init = p ? p->nd_next : 0; + args->first_post_arg = p ? p->nd_pid : 0; + + args->rest_arg = r; + args->block_arg = b; + + args->opt_args = o; - if (p) { - i2 = p->nd_next; - node->nd_next->nd_next = NEW_ARGS_AUX(p->nd_pid, p->nd_plen); - } - else if (i1) { - node->nd_next->nd_next = NEW_ARGS_AUX(0, 0); - } - if (i1 || i2) { - node->nd_next->nd_next->nd_next = NEW_NODE(NODE_AND, i1, i2, 0); - } ruby_sourceline = saved_line; - return node; + return NEW_NODE(NODE_ARGS, 0, 0, args); } #endif /* !RIPPER */