summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-02-24 02:07:05 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-02-24 02:07:05 +0000
commit0fe72040e4c278bfafe232dc44551de2dfac85e2 (patch)
treeb94399addca7cc57efeb4ae755c408a09d99d115
parentc5148e038316b3351b4c831773b83e08c11c20fb (diff)
* parse.y, node.h, compile.c: change node tree structure. a purpose
of this change is to unify argument structure of method and block. this change prohibits duplicate block parameter name. new argument infromation: 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, ->] * vm_macro.def: ditto. * gc.c: ditto. * iseq.c: ditto. * compile.h: fix debug function name. * test/ripper/test_scanner_events.rb: |_,_,foo| -> |_1,_2,foo| * test/ruby/test_lambda.rb: disalbe test temporarily. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11840 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog24
-rw-r--r--compile.c115
-rw-r--r--compile.h18
-rw-r--r--gc.c4
-rw-r--r--iseq.c11
-rw-r--r--node.h14
-rw-r--r--parse.y141
-rw-r--r--test/ripper/test_scanner_events.rb2
-rw-r--r--test/ruby/test_lambda.rb2
-rw-r--r--vm_macro.def81
10 files changed, 251 insertions, 161 deletions
diff --git a/ChangeLog b/ChangeLog
index f58fd7af76..92fa655fc7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+Sat Feb 24 10:49:55 2007 Koichi Sasada <ko1@atdot.net>
+
+ * parse.y, node.h, compile.c: change node tree structure. a purpose
+ of this change is to unify argument structure of method and block.
+ this change prohibits duplicate block parameter name.
+ new argument infromation:
+ 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, ->]
+
+ * vm_macro.def: ditto.
+
+ * gc.c: ditto.
+
+ * iseq.c: ditto.
+
+ * compile.h: fix debug function name.
+
+ * test/ripper/test_scanner_events.rb: |_,_,foo| -> |_1,_2,foo|
+
+ * test/ruby/test_lambda.rb: disalbe test temporarily.
+
Sat Feb 24 10:46:28 2007 Koichi Sasada <ko1@atdot.net>
* test/testunit/test_testcase.rb: catch up with current instance
diff --git a/compile.c b/compile.c
index ffc9510691..d498f4a3e2 100644
--- a/compile.c
+++ b/compile.c
@@ -147,7 +147,6 @@ iseq_compile(VALUE self, NODE *narg)
debugs("[compile step 1 (traverse each node)]\n");
-
iseq->node = node;
if (iseq->type == ISEQ_TYPE_BLOCK) {
@@ -1035,7 +1034,7 @@ set_block_local_tbl(rb_iseq_t *iseq, NODE * node, LINK_ANCHOR *anchor)
}
}
- if (iseq->arg_opts || iseq->arg_rest) {
+ if (iseq->arg_opts || iseq->arg_rest || iseq->arg_block) {
iseq->arg_simple = 0;
}
else {
@@ -1077,9 +1076,96 @@ get_dyna_var_idx(rb_iseq_t *iseq, ID id, int *level, int *ls)
return -1;
}
-/**
+#if 1
+
+static int
+set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_arg)
+{
+ NODE *node_aux = node_arg->nd_next;
+ int mandatory_len = 0;
+ NODE *node_opt = 0;
+ ID rest_id = 0;
+ ID block_id = 0;
+ ID post_start_id = 0;
+ int post_len = 0;
+ NODE *node_init = 0;
+
+ iseq->argc = node_arg->nd_frml;
+ node_opt = node_arg->nd_opt;
+
+ if (node_aux) {
+ rest_id = node_aux->nd_rest;
+ block_id = (ID)node_aux->nd_body;
+ node_aux = node_aux->nd_next;
+
+ if (node_aux) {
+ post_start_id = node_aux->nd_pid;
+ post_len = node_aux->nd_plen;
+ node_init = node_aux->nd_next;
+ }
+ }
+
+ if (node_init) {
+ COMPILE(optargs, "arguments", node_init);
+ }
+
+ if (node_opt) {
+ NODE *node = node_opt;
+ LABEL *label;
+ VALUE labels = rb_ary_new();
+ int i = 0, j;
+
+ while (node) {
+ label = NEW_LABEL(nd_line(node));
+ rb_ary_push(labels, (VALUE)label | 1);
+ ADD_LABEL(optargs, label);
+ COMPILE_POPED(optargs, "optarg", node->nd_body);
+
+ node = node->nd_next;
+ i += 1;
+ }
+ /* last label */
+ label = NEW_LABEL(nd_line(node_arg));
+ rb_ary_push(labels, (VALUE)label | 1);
+ ADD_LABEL(optargs, label);
+ i += 1;
+
+ iseq->arg_opts = i;
+ iseq->arg_opt_tbl = ALLOC_N(VALUE, i);
+ MEMCPY(iseq->arg_opt_tbl, RARRAY_PTR(labels), VALUE, i);
+ for (j = 0; j < i; j++) {
+ iseq->arg_opt_tbl[j] &= ~1;
+ }
+ }
+ else {
+ iseq->arg_opts = 0;
+ }
+
+ if ((long)rest_id == -1) {
+ iseq->arg_rest = get_dyna_var_idx_at_raw(iseq, 0 /* dummy var */);
+ }
+ else if (rest_id) {
+ iseq->arg_rest = get_dyna_var_idx_at_raw(iseq, rest_id);
+ }
+ if (iseq->arg_rest == -1) rb_bug("arg_rest: -1");
+
+
+ if (block_id) {
+ iseq->arg_block = get_dyna_var_idx_at_raw(iseq, block_id);
+ }
+
+ if (iseq->arg_rest != 0 || iseq->arg_opts != 0 || iseq->arg_block != 0) {
+ iseq->arg_simple = 0;
+ }
+ else {
+ iseq->arg_simple = 1;
+ }
+
+ return COMPILE_OK;
+}
+
+#else
- */
static int
set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE * node)
{
@@ -1121,7 +1207,9 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE * node)
iseq->arg_opts = i;
iseq->arg_opt_tbl = ALLOC_N(VALUE, i);
+
MEMCPY(iseq->arg_opt_tbl, RARRAY_PTR(labels), VALUE, i);
+
for (j = 0; j < i; j++) {
iseq->arg_opt_tbl[j] &= ~1;
}
@@ -1144,6 +1232,7 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE * node)
}
return COMPILE_OK;
}
+#endif
static int
set_localtbl(rb_iseq_t *iseq, ID *tbl)
@@ -3681,6 +3770,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
int idx = liseq->local_size - i;
ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
}
+
if (!liseq->arg_simple) {
if (liseq->arg_opts) {
/* optional arguments */
@@ -3693,13 +3783,20 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
i += j;
argc = INT2FIX(i);
}
+
if (liseq->arg_rest) {
/* rest arguments */
- int idx = liseq->local_size - liseq->arg_rest + 1;
- ADD_INSN1(args, nd_line(node), getlocal,
- INT2FIX(idx));
- argc = INT2FIX(liseq->arg_rest);
- flag |= VM_CALL_ARGS_SPLAT_BIT;
+
+ if (liseq->arg_rest == -1) {
+ /* TODO */
+ }
+ else {
+ int idx = liseq->local_size - liseq->arg_rest + 1;
+ ADD_INSN1(args, nd_line(node), getlocal,
+ INT2FIX(idx));
+ argc = INT2FIX(liseq->arg_rest);
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+ }
}
}
}
diff --git a/compile.h b/compile.h
index 9d4ba5baf6..f1e7bfa86a 100644
--- a/compile.h
+++ b/compile.h
@@ -41,27 +41,27 @@
#if CPDEBUG > 0
#define debugp(header, value) \
- (debug_indent(0, CPDEBUG, gl_node_level * 2), \
+ (ruby_debug_indent(0, CPDEBUG, gl_node_level * 2), \
ruby_debug_value(0, CPDEBUG, header, value))
#define debugi(header, id) \
- (debug_indent(0, CPDEBUG, gl_node_level * 2), \
- debug_id(0, CPDEBUG, header, id))
+ (ruby_debug_indent(0, CPDEBUG, gl_node_level * 2), \
+ ruby_debug_id(0, CPDEBUG, header, id))
#define debugp_param(header, value) \
- (debug_indent(1, CPDEBUG, gl_node_level * 2), \
+ (ruby_debug_indent(1, CPDEBUG, gl_node_level * 2), \
ruby_debug_value(1, CPDEBUG, header, value))
#define debugp_verbose(header, value) \
- (debug_indent(2, CPDEBUG, gl_node_level * 2), \
+ (ruby_debug_indent(2, CPDEBUG, gl_node_level * 2), \
ruby_debug_value(2, CPDEBUG, header, value))
#define debugp_verbose_node(header, value) \
- (debug_indent(10, CPDEBUG, gl_node_level * 2), \
+ (ruby_debug_indent(10, CPDEBUG, gl_node_level * 2), \
ruby_debug_value(10, CPDEBUG, header, value))
#define debug_nodeprint(node) \
- debug_indent(-1, CPDEBUG, gl_node_level*2); \
+ ruby_debug_indent(-1, CPDEBUG, gl_node_level*2); \
printf("node: %s (%d)\n", ruby_node_name(nd_type(node)), nd_line(node)); \
gl_node_level ++;
@@ -91,8 +91,8 @@ r_value(VALUE value)
#endif
#if CPDEBUG > 1
-#define debugs debug_indent(-1, CPDEBUG, gl_node_level*2), printf
-#define debug_compile(msg, v) (debug_indent(-1, CPDEBUG, gl_node_level*2), printf("%s", msg), (v))
+#define debugs ruby_debug_indent(-1, CPDEBUG, gl_node_level*2), printf
+#define debug_compile(msg, v) (ruby_debug_indent(-1, CPDEBUG, gl_node_level*2), printf("%s", msg), (v))
#else
#define debugs if(0)printf
#define debug_compile(msg, v) (v)
diff --git a/gc.c b/gc.c
index bbf3694ff9..987a5f842e 100644
--- a/gc.c
+++ b/gc.c
@@ -844,7 +844,6 @@ gc_mark_children(VALUE ptr, int lev)
case NODE_RESCUE:
case NODE_RESBODY:
case NODE_CLASS:
- case NODE_ARGS:
case NODE_BLOCK_PASS:
gc_mark((VALUE)obj->as.node.u2.node, lev);
/* fall through */
@@ -859,11 +858,13 @@ gc_mark_children(VALUE ptr, int lev)
case NODE_CALL:
case NODE_DEFS:
case NODE_OP_ASGN1:
+ case NODE_ARGS:
gc_mark((VALUE)obj->as.node.u1.node, lev);
/* fall through */
case NODE_SUPER: /* 3 */
case NODE_FCALL:
case NODE_DEFN:
+ case NODE_ARGS_AUX:
ptr = (VALUE)obj->as.node.u3.node;
goto again;
@@ -922,6 +923,7 @@ gc_mark_children(VALUE ptr, int lev)
case NODE_SCOPE: /* 2,3 */
case NODE_CDECL:
+ case NODE_OPT_ARG:
gc_mark((VALUE)obj->as.node.u3.node, lev);
ptr = (VALUE)obj->as.node.u2.node;
goto again;
diff --git a/iseq.c b/iseq.c
index 1680aa4aa5..1fc0cff963 100644
--- a/iseq.c
+++ b/iseq.c
@@ -542,10 +542,15 @@ insn_operand_intern(rb_iseq_t *iseq,
case TS_LINDEX:
{
rb_iseq_t *ip = iseq->local_iseq;
+ int lidx = ip->local_size - op + 1;
+ ID id = ip->local_tbl[lidx];
- ret =
- rb_str_new2(
- rb_id2name(ip->local_tbl[ip->local_size - op + 1]));
+ if (id) {
+ ret = rb_str_new2(rb_id2name(id));
+ }
+ else {
+ ret = rb_str_new2("*");
+ }
break;
}
case TS_DINDEX:{
diff --git a/node.h b/node.h
index cf051c096b..c21158f9da 100644
--- a/node.h
+++ b/node.h
@@ -87,6 +87,8 @@ enum node_type {
NODE_DREGX,
NODE_DREGX_ONCE,
NODE_ARGS,
+ NODE_ARGS_AUX,
+ NODE_OPT_ARG,
NODE_POSTARG,
NODE_ARGSCAT,
NODE_ARGSPUSH,
@@ -209,9 +211,11 @@ typedef struct RNode {
#define nd_lit u1.value
-#define nd_frml u3.value
-#define nd_rest u2.node
+#define nd_frml u2.argc
+#define nd_rest u1.id
#define nd_opt u1.node
+#define nd_pid u1.id
+#define nd_plen u2.argc
#define nd_recv u1.node
#define nd_mid u2.id
@@ -315,8 +319,10 @@ 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(f,o,r) NEW_NODE(NODE_ARGS,o,r,f)
-#define NEW_POSTARG(r,m) NEW_NODE(NODE_POSTARG,m,0,r)
+#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)
#define NEW_ARGSCAT(a,b) NEW_NODE(NODE_ARGSCAT,a,b,0)
#define NEW_ARGSPUSH(a,b) NEW_NODE(NODE_ARGSPUSH,a,b,0)
#define NEW_SPLAT(a) NEW_NODE(NODE_SPLAT,a,0,0)
diff --git a/parse.y b/parse.y
index e4958888f2..dfba404da5 100644
--- a/parse.y
+++ b/parse.y
@@ -346,7 +346,7 @@ static NODE *evstr2dstr(NODE*);
static NODE *call_op_gen(struct parser_params*,NODE*,ID,int,NODE*);
#define call_op(recv,id,narg,arg1) call_op_gen(parser, recv,id,narg,arg1)
-static NODE *new_args_gen(struct parser_params*,VALUE,NODE*,NODE*,NODE*,NODE*);
+static NODE *new_args_gen(struct parser_params*,int,NODE*,ID,NODE*,ID);
#define new_args(f,o,r,p,b) new_args_gen(parser, f,o,r,p,b)
static void shadowing_lvar_gen(struct parser_params*,ID);
#define shadowing_lvar(name) shadowing_lvar_gen(parser, name)
@@ -617,15 +617,15 @@ static void ripper_compile_error(struct parser_params*, const char *fmt, ...);
%type <node> open_args paren_args opt_paren_args
%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
%type <node> mrhs superclass block_call block_command
-%type <node> f_arglist f_args f_rest_arg f_post_arg
-%type <node> f_optarg f_opt f_block_arg opt_f_block_arg
+%type <node> f_arglist f_args f_post_arg
+%type <node> f_optarg f_opt
%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
%type <node> block_param opt_block_param block_param_def bparam_list bparam_item
%type <node> opt_bv_decl bv_decls bvar lambda f_larglist lambda_body
%type <node> brace_block cmd_brace_block do_block lhs none fitem
%type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post
%type <id> fsym variable sym symbol operation operation2 operation3
-%type <id> cname fname op f_norm_arg
+%type <id> cname fname op f_norm_arg f_rest_arg f_block_arg opt_f_block_arg
%type <val> f_arg
/*%%%*/
/*%
@@ -4151,13 +4151,7 @@ f_norm_arg : tCONSTANT
/*%%%*/
if (!is_local_id($1))
yyerror("formal argument must be local variable");
- if (dyna_in_block()) {
- shadowing_lvar($1);
- dyna_var($1);
- }
- else {
- local_cnt($1);
- }
+ shadowing_lvar($1);
$$ = $1;
/*%
$$ = $1;
@@ -4167,32 +4161,18 @@ f_norm_arg : tCONSTANT
f_arg : f_norm_arg
{
- /*%%%*/
- VALUE arg = ID2SYM($1);
- /*%
- VALUE arg = $1;
- %*/
- $$ = rb_ary_new3(1, arg);
+ $$ = 1;
}
| f_arg ',' f_norm_arg
{
- /*%%%*/
- VALUE arg = ID2SYM($3);
- $$ = $1;
- if (rb_ary_includes($$, arg)) {
- yyerror("duplicated argument name");
- }
- rb_ary_push($$, arg);
- /*%
- rb_ary_push($$, $3);
- %*/
+ $$ = $1 + 1;
}
;
f_post_arg : f_norm_arg
{
/*%%%*/
- $$ = NEW_LIST(assignable($1, 0));
+ $$ = NEW_ARGS_AUX($1, 1);
/*%
$$ = mlhs_add(mlhs_new(), $1);
%*/
@@ -4200,7 +4180,8 @@ f_post_arg : f_norm_arg
| f_post_arg ',' f_norm_arg
{
/*%%%*/
- $$ = list_append($1, assignable($3, 0));
+ $1->nd_alen++;
+ $$ = $1;
/*%
$$ = mlhs_add($1, $3);
%*/
@@ -4212,11 +4193,8 @@ f_opt : tIDENTIFIER '=' arg_value
/*%%%*/
if (!is_local_id($1))
yyerror("formal argument must be local variable");
- if (dyna_in_block()) {
- shadowing_lvar($1);
- dyna_var($1);
- }
- $$ = assignable($1, $3);
+ shadowing_lvar($1);
+ $$ = NEW_OPT_ARG(0, assignable($1, $3));
/*%
$$ = rb_assoc_new($1, $3);
%*/
@@ -4226,8 +4204,7 @@ f_opt : tIDENTIFIER '=' arg_value
f_optarg : f_opt
{
/*%%%*/
- $$ = NEW_BLOCK($1);
- $$->nd_end = $$;
+ $$ = $1;
/*%
$$ = rb_ary_new3(1, $1);
%*/
@@ -4235,7 +4212,13 @@ f_optarg : f_opt
| f_optarg ',' f_opt
{
/*%%%*/
- $$ = block_append($1, $3);
+ NODE *opts = $1;
+
+ while (opts->nd_next) {
+ opts = opts->nd_next;
+ }
+ opts->nd_next = $3;
+ $$ = $1;
/*%
$$ = rb_ary_push($1, $3);
%*/
@@ -4251,11 +4234,8 @@ f_rest_arg : restarg_mark tIDENTIFIER
/*%%%*/
if (!is_local_id($2))
yyerror("rest argument must be local variable");
- if (dyna_in_block()) {
- shadowing_lvar($2);
- dyna_var($2);
- }
- $$ = assignable($2, 0);
+ shadowing_lvar($2);
+ $$ = $2;
/*%
$$ = dispatch1(restparam, $2);
%*/
@@ -4264,10 +4244,11 @@ f_rest_arg : restarg_mark tIDENTIFIER
{
/*%%%*/
if (dyna_in_block()) {
- $$ = NEW_DASGN_CURR(internal_id(), 0);
+ $$ = internal_id();
}
else {
- $$ = NEW_NODE(NODE_LASGN,0,0,local_append(0));
+ local_append(0);
+ $$ = -1;
}
/*%
$$ = dispatch1(restparam, Qnil);
@@ -4286,14 +4267,8 @@ f_block_arg : blkarg_mark tIDENTIFIER
yyerror("block argument must be local variable");
else if (!dyna_in_block() && local_id($2))
yyerror("duplicated block argument name");
- if (dyna_in_block()) {
- shadowing_lvar($2);
- dyna_var($2);
- $$ = assignable($2, 0);
- }
- else {
- $$ = NEW_BLOCK_ARG($2);
- }
+ shadowing_lvar($2);
+ $$ = $2;
/*%
$$ = $2;
%*/
@@ -4305,6 +4280,9 @@ opt_f_block_arg : ',' f_block_arg
$$ = $2;
}
| none
+ {
+ $$ = 0 ;
+ }
;
singleton : var_ref
@@ -7314,9 +7292,21 @@ assignable_gen(struct parser_params *parser, ID id, NODE *val)
static void
shadowing_lvar_gen(struct parser_params *parser, ID name)
{
- if (dvar_defined(name) || local_id(name)) {
- rb_warningS("shadowing outer local variable - %s", rb_id2name(name));
- }
+ if (dyna_in_block()) {
+ if (dvar_curr(name)) {
+ yyerror("duplicated argument name");
+ }
+ else if (dvar_defined(name) || local_id(name)) {
+ rb_warningS("shadowing outer local variable - %s", rb_id2name(name));
+ }
+ dyna_var(name);
+ }
+ else {
+ if (local_id(name)) {
+ yyerror("duplicated argument name");
+ }
+ local_cnt(name);
+ }
}
static NODE*
@@ -7966,47 +7956,14 @@ arg_dup_check(ID vid, VALUE m, VALUE list, NODE *node)
}
static NODE*
-new_args_gen(struct parser_params *parser, VALUE m, NODE *o, NODE *r, NODE *p, NODE *b)
+new_args_gen(struct parser_params *parser, int m, NODE *o, ID r, NODE *p, ID b)
{
int saved_line = ruby_sourceline;
- NODE *node;
- VALUE list;
+ NODE *node = NEW_ARGS(m, o);
- list = rb_ary_new();
- node = o;
- while (node) {
- if (!node->nd_head) break;
- if (arg_dup_check(node->nd_head->nd_vid, m, list, node)) {
- yyerror("duplicated optional argument name");
- return 0;
- }
- node = node->nd_next;
- }
- if (RTEST(r)) {
- if (arg_dup_check(r->nd_vid, m, list, r)) {
- yyerror("duplicated rest argument name");
- return 0;
- }
- }
+ node->nd_next = NEW_ARGS_AUX(r, b);
if (p) {
- node = p;
- while (node) {
- if (!node->nd_head) break;
- if (arg_dup_check(node->nd_head->nd_vid, m, list, node)) {
- yyerror("duplicated argument name");
- return 0;
- }
- node = node->nd_next;
- }
- r = NEW_POSTARG(r, p);
- }
- node = NEW_ARGS(m, o, r);
- if (b) {
- if (arg_dup_check(b->nd_vid, m, list, b)) {
- yyerror("duplicated block argument name");
- return 0;
- }
- node = block_append(node, b);
+ node->nd_next->nd_next = p;
}
ruby_sourceline = saved_line;
return node;
diff --git a/test/ripper/test_scanner_events.rb b/test/ripper/test_scanner_events.rb
index 644f9edb29..4389946104 100644
--- a/test/ripper/test_scanner_events.rb
+++ b/test/ripper/test_scanner_events.rb
@@ -17,7 +17,7 @@ class TestRipper_ScannerEvents < Test::Unit::TestCase
def scan(target, str)
sym = "on_#{target}".intern
- Ripper.lex(str).select {|_,type,_| type == sym }.map {|_,_,tok| tok }
+ Ripper.lex(str).select {|_1,type,_2| type == sym }.map {|_1,_2,tok| tok }
end
def test_tokenize
diff --git a/test/ruby/test_lambda.rb b/test/ruby/test_lambda.rb
index b4f0dac658..6105f5d122 100644
--- a/test/ruby/test_lambda.rb
+++ b/test/ruby/test_lambda.rb
@@ -1,5 +1,7 @@
require 'test/unit'
+__END__
+
class TestLambdaParameters < Test::Unit::TestCase
def test_call_simple
assert_equal(1, ->(a){ a }.call(1))
diff --git a/vm_macro.def b/vm_macro.def
index 28f0ed7e4d..3d6c66402c 100644
--- a/vm_macro.def
+++ b/vm_macro.def
@@ -86,7 +86,8 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
GetISeqPtr(niseqval, niseq);
clear_local_size = niseq->local_size - num;
- /* set arguments */
+
+ /* simple (only mandatory) arguments */
if (niseq->arg_simple) {
if (niseq->argc != num) {
rb_raise(rb_eArgError, "wrong number of arguments (%lu for %d)",
@@ -94,7 +95,7 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
}
}
else {
- /* check optional arguments */
+ /* optional arguments */
if (niseq->arg_opts) {
int iseq_argc = niseq->argc;
int opts = niseq->arg_opts - 1;
@@ -110,10 +111,9 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
(unsigned long)num, iseq_argc);
}
- if (0) {
- printf("num: %lu, opts: %d, iseq_argc: %d\n",
- (unsigned long)num, opts, iseq_argc);
- }
+ if (0) printf("num: %lu, opts: %d, iseq_argc: %d\n",
+ (unsigned long)num, opts, iseq_argc);
+
if (num - iseq_argc < opts) {
opt_pc = niseq->arg_opt_tbl[num - iseq_argc];
sp += opts - (num - iseq_argc);
@@ -124,23 +124,17 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
opt_pc = niseq->arg_opt_tbl[opts];
}
}
- /* check rest */
- if (niseq->arg_rest == -1) {
- if (niseq->arg_opts) {
- num = niseq->argc + niseq->arg_opts;
- }
- else {
- num = niseq->argc;
- }
- sp = &rsp[1 + num + 1];
- }
- else if (niseq->arg_rest != 0) {
+
+ /* rest argument */
+ if (niseq->arg_rest != 0) {
int rest = niseq->arg_rest - 1;
int pack_size = num - rest;
+
if (0) {
printf("num: %lu, rest: %d, ps: %d\n",
(unsigned long)num, niseq->arg_rest, pack_size);
}
+
if (pack_size < 0) {
rb_raise(rb_eArgError,
"wrong number of arguments (%lu for %d)",
@@ -165,6 +159,10 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
(niseq->arg_opts
&& num == niseq->argc + niseq->arg_opts - 1)
|| num == niseq->argc)) {
+
+ if (0) printf("num: %d, rest: %d, opts: %d, argc: %d\n",
+ num, niseq->arg_rest, niseq->arg_opts, niseq->argc);
+
rb_raise(rb_eArgError,
"wrong number of arguments (%lu for %d)",
(unsigned long)num, niseq->argc);
@@ -189,6 +187,7 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
clear_local_size--;
}
}
+
/* stack overflow check */
if (CHECK_STACK_OVERFLOW(th, GET_CFP(), niseq->stack_max + 0x100)) {
rb_exc_raise(sysstack_error);
@@ -198,32 +197,30 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
*sp++ = Qnil;
}
- {
- if (0 && (flag & VM_CALL_TAILCALL_BIT)) {
- th->cfp++;
- push_frame(th, niseq, FRAME_MAGIC_METHOD,
- recv, (VALUE) blockptr,
- niseq->iseq_encoded + opt_pc, sp, 0, 0);
- }
- else if (0 &&
- (flag & VM_CALL_TAILRECURSION_BIT) && niseq == GET_ISEQ()) {
- /* do nothing */
- GET_CFP()->self = recv;
- SET_LFP(sp);
- SET_DFP(sp);
- *sp++ = (VALUE) blockptr;
- reg_cfp->sp = sp;
- reg_cfp->bp = sp;
- SET_PC(niseq->iseq_encoded + opt_pc);
- }
- else {
- push_frame(th, niseq,
- FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
- niseq->iseq_encoded + opt_pc, sp, 0, 0);
- reg_cfp->sp = rsp;
- }
- RESTORE_REGS();
+ if (0 && (flag & VM_CALL_TAILCALL_BIT)) {
+ th->cfp++;
+ push_frame(th, niseq, FRAME_MAGIC_METHOD,
+ recv, (VALUE) blockptr,
+ niseq->iseq_encoded + opt_pc, sp, 0, 0);
+ }
+ else if (0 &&
+ (flag & VM_CALL_TAILRECURSION_BIT) && niseq == GET_ISEQ()) {
+ /* do nothing */
+ GET_CFP()->self = recv;
+ SET_LFP(sp);
+ SET_DFP(sp);
+ *sp++ = (VALUE) blockptr;
+ reg_cfp->sp = sp;
+ reg_cfp->bp = sp;
+ SET_PC(niseq->iseq_encoded + opt_pc);
+ }
+ else {
+ push_frame(th, niseq,
+ FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
+ niseq->iseq_encoded + opt_pc, sp, 0, 0);
+ reg_cfp->sp = rsp;
}
+ RESTORE_REGS();
}
MACRO macro_eval_invoke_method(recv, klass, id, num, mn, blockptr)