summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-13 08:34:43 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-13 08:34:43 +0000
commitffd3cbdc759841c984ec35bfecfb9f7ed28d4faa (patch)
tree9977cb9dc1d1c5f986736c558311e9bad2d355a2 /vm_insnhelper.c
parentdb31b3dad519f755358f0a96baad5c378e7c7972 (diff)
* vm_insnhelper.c (vm_caller_setup_args): save and restore
ci->argc and ci->blockptr before and after method invocations because these method dispatches override call_info. * bootstraptest/test_method.rb: add tests for this fix. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37641 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 32b0851320..3e1ca3866c 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1036,6 +1036,12 @@ vm_base_ptr(rb_control_frame_t *cfp)
static void
vm_caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
{
+#define SAVE_RESTORE_CI(expr, ci) do { \
+ int saved_argc = (ci)->argc; rb_block_t *saved_blockptr = (ci)->blockptr; /* save */ \
+ expr; \
+ (ci)->argc = saved_argc; (ci)->blockptr = saved_blockptr; /* restore */ \
+} while (0)
+
if (UNLIKELY(ci->flag & VM_CALL_ARGS_BLOCKARG)) {
rb_proc_t *po;
VALUE proc;
@@ -1044,7 +1050,10 @@ vm_caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, rb_call_inf
if (proc != Qnil) {
if (!rb_obj_is_proc(proc)) {
- VALUE b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc");
+ VALUE b;
+
+ SAVE_RESTORE_CI(b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc"), ci);
+
if (NIL_P(b) || !rb_obj_is_proc(b)) {
rb_raise(rb_eTypeError,
"wrong argument type %s (expected Proc)",
@@ -1069,7 +1078,9 @@ vm_caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, rb_call_inf
VALUE ary = *(cfp->sp - 1);
VALUE *ptr;
int i;
- VALUE tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a");
+ VALUE tmp;
+
+ SAVE_RESTORE_CI(tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a"), ci);
if (NIL_P(tmp)) {
/* do nothing */