diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-06-24 08:40:45 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-06-24 08:40:45 +0000 |
commit | adc677eb5cd3aed1986c3316d5b98ed942f544d5 (patch) | |
tree | 8c50f9cef922a9fce4f7cc68adce20599b1df35d /vm.c | |
parent | d1bd418715091794dc207198a0fe4152b5f40cb1 (diff) | |
download | ruby-adc677eb5cd3aed1986c3316d5b98ed942f544d5.tar.gz |
* insnhelper.h: change CHECK_STACK_OVERFLOW() to throw exception.
* vm.c (caller_setup_arg), vm_macro.def: remove
macro_eval_setup_send_arguments and add caller_setup_arg().
* insns.def: ditto.
* bootstraptest/test_method.rb: add splat arg tests.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12596 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm.c')
-rw-r--r-- | vm.c | 62 |
1 files changed, 62 insertions, 0 deletions
@@ -282,6 +282,68 @@ callee_setup_arg(rb_thread_t *th, rb_iseq_t *iseq, } } +static inline int +caller_setup_args(rb_thread_t *th, rb_control_frame_t *cfp, + VALUE flag, int argc, rb_iseq_t *blockiseq, rb_block_t **block) +{ + rb_block_t *blockptr = 0; + + if (flag & VM_CALL_ARGS_BLOCKARG_BIT) { + rb_proc_t *po; + VALUE proc; + + proc = *(--cfp->sp); + + if (proc != Qnil) { + if (!rb_obj_is_proc(proc)) { + proc = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc"); + if (!rb_obj_is_proc(proc)) { + rb_raise(rb_eTypeError, + "wrong argument type %s (expected Proc)", + rb_obj_classname(proc)); + } + } + GetProcPtr(proc, po); + blockptr = &po->block; + RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp)->proc = proc; + *block = blockptr; + } + } + else if (blockiseq) { + blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp); + blockptr->iseq = blockiseq; + blockptr->proc = 0; + *block = blockptr; + } + + /* expand top of stack? */ + if (flag & VM_CALL_ARGS_SPLAT_BIT) { + VALUE ary = *(cfp->sp - 1); + VALUE *ptr, *dst; + int i; + VALUE tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_splat"); + + if (NIL_P(tmp)) { + /* do nothing */ + } + else { + int len = RARRAY_LEN(tmp); + ptr = RARRAY_PTR(tmp); + cfp->sp -= 1; + + CHECK_STACK_OVERFLOW(cfp, len); + + for (i = 0; i < len; i++) { + *cfp->sp++ = ptr[i]; + } + argc += i-1; + } + } + + return argc; +} + + /* Env */ static void |