summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-06-24 08:40:45 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-06-24 08:40:45 +0000
commitadc677eb5cd3aed1986c3316d5b98ed942f544d5 (patch)
tree8c50f9cef922a9fce4f7cc68adce20599b1df35d /vm.c
parentd1bd418715091794dc207198a0fe4152b5f40cb1 (diff)
* 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.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/vm.c b/vm.c
index 376b5efc15..f4e37d28a7 100644
--- a/vm.c
+++ b/vm.c
@@ -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