mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
db31b3dad5
commit
ffd3cbdc75
3 changed files with 79 additions and 2 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
Tue Nov 13 17:28:47 2012 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
Tue Nov 13 16:38:02 2012 NARUSE, Yui <naruse@ruby-lang.org>
|
Tue Nov 13 16:38:02 2012 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
* common.mk (dmyprobes.h): always create for make dist.
|
* common.mk (dmyprobes.h): always create for make dist.
|
||||||
|
|
|
@ -1204,3 +1204,61 @@ assert_equal 'ok', %q{
|
||||||
'ok'
|
'ok'
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_equal 'DC', %q{
|
||||||
|
$result = []
|
||||||
|
|
||||||
|
class C
|
||||||
|
def foo *args
|
||||||
|
$result << 'C'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
class D
|
||||||
|
def foo *args
|
||||||
|
$result << 'D'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
o1 = $o1 = C.new
|
||||||
|
o2 = $o2 = D.new
|
||||||
|
|
||||||
|
args = Object.new
|
||||||
|
def args.to_a
|
||||||
|
test1 $o2, nil
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
def test1 o, args
|
||||||
|
o.foo(*args)
|
||||||
|
end
|
||||||
|
test1 o1, args
|
||||||
|
$result.join
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal 'DC', %q{
|
||||||
|
$result = []
|
||||||
|
|
||||||
|
class C
|
||||||
|
def foo *args
|
||||||
|
$result << 'C'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
class D
|
||||||
|
def foo *args
|
||||||
|
$result << 'D'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
o1 = $o1 = C.new
|
||||||
|
o2 = $o2 = D.new
|
||||||
|
|
||||||
|
block = Object.new
|
||||||
|
def block.to_proc
|
||||||
|
test2 $o2, %w(a, b, c), nil
|
||||||
|
Proc.new{}
|
||||||
|
end
|
||||||
|
def test2 o, args, block
|
||||||
|
o.foo(*args, &block)
|
||||||
|
end
|
||||||
|
test2 o1, [], block
|
||||||
|
$result.join
|
||||||
|
}
|
||||||
|
|
|
@ -1036,6 +1036,12 @@ vm_base_ptr(rb_control_frame_t *cfp)
|
||||||
static void
|
static void
|
||||||
vm_caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
|
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)) {
|
if (UNLIKELY(ci->flag & VM_CALL_ARGS_BLOCKARG)) {
|
||||||
rb_proc_t *po;
|
rb_proc_t *po;
|
||||||
VALUE proc;
|
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 (proc != Qnil) {
|
||||||
if (!rb_obj_is_proc(proc)) {
|
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)) {
|
if (NIL_P(b) || !rb_obj_is_proc(b)) {
|
||||||
rb_raise(rb_eTypeError,
|
rb_raise(rb_eTypeError,
|
||||||
"wrong argument type %s (expected Proc)",
|
"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 ary = *(cfp->sp - 1);
|
||||||
VALUE *ptr;
|
VALUE *ptr;
|
||||||
int i;
|
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)) {
|
if (NIL_P(tmp)) {
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue