mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* yarvcore.h, compile.c (set_arguments): support post arguments.
* test/ruby/test_method.rb: add tests for above. * test/ruby/test_proc.rb: ditto. * proc.c: fix an arity bug ([ruby-core:11029]). * vm.c, vm.h, insns.def, vm_dump.h: fix bmethod process. * vm.c: support block argument on block parameter. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12231 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ea2cb282ae
commit
75d28f8870
12 changed files with 148 additions and 44 deletions
77
compile.c
77
compile.c
|
|
@ -849,6 +849,83 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
|
|||
if (iseq->arg_rest == -1) {
|
||||
rb_bug("arg_rest: -1");
|
||||
}
|
||||
|
||||
if (post_len) {
|
||||
/*
|
||||
* if rest.length < post_len
|
||||
* raise ArgumentError
|
||||
* end
|
||||
* post1 = rest.shift
|
||||
* post2 = rest.shift
|
||||
* ...
|
||||
*
|
||||
* #=> yarv insns
|
||||
* push rest
|
||||
* call :length
|
||||
* put 1
|
||||
* call :<
|
||||
* branchunless :success
|
||||
* put ArgumentsError
|
||||
* put "wrong number of arugments (%d of %d)"
|
||||
* call :new, 1
|
||||
* call :raise
|
||||
* success:
|
||||
* push rest
|
||||
* call :shift
|
||||
* set post1
|
||||
* push rest
|
||||
* call :shift
|
||||
* set post2
|
||||
* ...
|
||||
*/
|
||||
LABEL *lsuccess = NEW_LABEL(nd_line(node_args));
|
||||
int i;
|
||||
|
||||
#define GET_LOCAL(idx) do { \
|
||||
if (iseq->type == ISEQ_TYPE_METHOD) { \
|
||||
ADD_INSN1(optargs, nd_line(node_args), getlocal, INT2FIX(iseq->local_size - (idx) + 1)); \
|
||||
} \
|
||||
else { \
|
||||
ADD_INSN2(optargs, nd_line(node_args), getdynamic, INT2FIX(iseq->local_size - (idx)), INT2FIX(0)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SET_LOCAL(idx) do { \
|
||||
if (iseq->type == ISEQ_TYPE_METHOD) { \
|
||||
ADD_INSN1(optargs, nd_line(node_args), setlocal, INT2FIX(iseq->local_size - (idx) + 1)); \
|
||||
} \
|
||||
else { \
|
||||
ADD_INSN2(optargs, nd_line(node_args), setdynamic, INT2FIX(iseq->local_size - (idx)), INT2FIX(0)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
GET_LOCAL(iseq->arg_rest);
|
||||
ADD_SEND (optargs, nd_line(node_args), ID2SYM(idLength), INT2FIX(0));
|
||||
ADD_INSN1(optargs, nd_line(node_args), putobject, INT2FIX(1));
|
||||
ADD_SEND (optargs, nd_line(node_args), ID2SYM(idLT), INT2FIX(1));
|
||||
ADD_INSNL(optargs, nd_line(node_args), branchunless, lsuccess);
|
||||
ADD_CALL_RECEIVER(optargs, nd_line(node_args));
|
||||
|
||||
/* error */
|
||||
ADD_INSN1(optargs, nd_line(node_args), putobject, rb_eArgError);
|
||||
ADD_INSN1(optargs, nd_line(node_args), putstring, rb_str_new2("wrong number of arguments"));
|
||||
ADD_SEND (optargs, nd_line(node_args), ID2SYM(rb_intern("new")), INT2FIX(1));
|
||||
ADD_CALL (optargs, nd_line(node_args), ID2SYM(rb_intern("raise")), INT2FIX(1));
|
||||
ADD_INSN (optargs, nd_line(node_args), pop); /* dummy */
|
||||
|
||||
ADD_LABEL(optargs, lsuccess);
|
||||
|
||||
for (i=0; i<post_len; i++) {
|
||||
GET_LOCAL(iseq->arg_rest);
|
||||
ADD_SEND (optargs, nd_line(node_args), ID2SYM(rb_intern("pop")),
|
||||
INT2FIX(0));
|
||||
SET_LOCAL(iseq->arg_rest + i + 1);
|
||||
}
|
||||
|
||||
iseq->arg_post_len = post_len;
|
||||
}
|
||||
#undef GET_LOCAL
|
||||
#undef SET_LOCAL
|
||||
}
|
||||
|
||||
if (block_id) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue