diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-05-02 02:26:03 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-05-02 02:26:03 +0000 |
commit | f53a94c83124ce44a53e4262cdd30ffa53016f1a (patch) | |
tree | 5717bdd70a5bfc613e4a0dd40eb5ad2011da29c5 | |
parent | 0cc90b386573acd30b2256c7ff72e7da10d77bc3 (diff) | |
download | ruby-f53a94c83124ce44a53e4262cdd30ffa53016f1a.tar.gz |
* compile.c: use Qtrue instead of 2.
* vm.c, insns.def: support "lambda" calling convention.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12240 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | compile.c | 5 | ||||
-rw-r--r-- | insns.def | 3 | ||||
-rw-r--r-- | vm.c | 37 |
4 files changed, 36 insertions, 15 deletions
@@ -1,3 +1,9 @@ +Wed May 2 11:22:52 2007 Koichi Sasada <ko1@atdot.net> + + * compile.c: use Qtrue instead of 2. + + * vm.c, insns.def: support "lambda" calling convention. + Wed May 2 06:46:43 2007 Nobuyoshi Nakada <nobu@ruby-lang.org> * error.c, parse.y, ruby.h (rb_compile_warn, rb_compile_warning): warn @@ -3702,6 +3702,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) p = p->nd_next, argc++) { /* count argc */ } + if (argc == 1) { COMPILE(args, "yield with an arg", node->nd_head); } @@ -3713,7 +3714,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) } else { if (nd_type(node->nd_head) == NODE_ARGSCAT) { - if (node->nd_state == 2) { + if (node->nd_state == Qtrue) { flag |= VM_CALL_ARGS_SPLAT_BIT; } @@ -3726,7 +3727,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) node->nd_head->nd_body); } else if (nd_type(node->nd_head) == NODE_SPLAT) { - if (node->nd_state == 2) { + if (node->nd_state == Qtrue) { flag |= VM_CALL_ARGS_SPLAT_BIT; } @@ -1335,6 +1335,7 @@ invokeblock VALUE *ptr = RARRAY_PTR(ary); VALUE *dst = GET_SP() - 1; int i, len = RARRAY_LEN(ary); + for (i = 0; i < len; i++) { dst[i] = ptr[i]; } @@ -1344,7 +1345,7 @@ invokeblock } INC_SP(-argc); - argc = th_yield_setup_args(iseq, argc, GET_SP()); + argc = th_yield_setup_args(iseq, argc, GET_SP(), 0); INC_SP(argc); push_frame(th, iseq, @@ -674,10 +674,10 @@ th_yield_with_cfunc(rb_thread_t *th, rb_block_t *block, } static inline int -th_yield_setup_args(rb_iseq_t *iseq, int argc, VALUE *argv) +th_yield_setup_args(rb_iseq_t *iseq, int argc, VALUE *argv, int lambda) { int i, arg_n = iseq->argc + (iseq->arg_rest == -1 ? 0 : 1); - + if (0) { /* for debug */ int i; GET_THREAD()->cfp->sp += argc; @@ -689,10 +689,11 @@ th_yield_setup_args(rb_iseq_t *iseq, int argc, VALUE *argv) printf("iseq argc: %d\n", iseq->argc); printf("iseq rest: %d\n", iseq->arg_rest); printf("iseq blck: %d\n", iseq->arg_block); + printf(" lambda: %s\n", lambda ? "true" : "false"); GET_THREAD()->cfp->sp -= argc; } - if (argc == 1 && TYPE(argv[0]) == T_ARRAY && arg_n != 1) { + if (lambda == 0 && argc == 1 && TYPE(argv[0]) == T_ARRAY && arg_n != 1) { VALUE ary = argv[0]; argc = RARRAY_LEN(ary); @@ -704,8 +705,8 @@ th_yield_setup_args(rb_iseq_t *iseq, int argc, VALUE *argv) } if (iseq->arg_rest == -1) { - if (iseq->argc == 1) { - if (argc != 1) { + if (lambda == 0 && iseq->argc == 1) { + if (argc > 1) { /* yield 1, 2, 3 for iter{|a| ...} * * ruby 1.8 warns on this timing. @@ -717,19 +718,31 @@ th_yield_setup_args(rb_iseq_t *iseq, int argc, VALUE *argv) } if (iseq->argc < argc) { - /* simple truncate */ - argc = iseq->argc; + if (lambda) { + rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", + argc, iseq->argc); + } + else { + /* simple truncate */ + argc = iseq->argc; + } } } else { int r = iseq->arg_rest; if (argc < r) { - /* TODO: check overflow */ - for (i=argc; i<r; i++) { - argv[i] = Qnil; + if (lambda) { + rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", + argc, iseq->argc); + } + else { + /* TODO: check overflow */ + for (i=argc; i<r; i++) { + argv[i] = Qnil; + } + argv[r] = rb_ary_new(); } - argv[r] = rb_ary_new(); } else { argv[r] = rb_ary_new4(argc-r, &argv[r]); @@ -764,7 +777,7 @@ invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self, int argc, VALUE *ar for (i=0; i<argc; i++) { th->cfp->sp[i] = argv[i]; } - argc = th_yield_setup_args(iseq, argc, th->cfp->sp); + argc = th_yield_setup_args(iseq, argc, th->cfp->sp, magic == FRAME_MAGIC_LAMBDA); th->cfp->sp += argc; push_frame(th, iseq, magic, |