Issue #8484 has been reported by naruse (Yui NARUSE).
Bug #8484: Restoring conditions through the ruby method call during VM
processing
Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: YARV
Target version: current: 2.1.0
ruby -v: ruby 2.1.0dev (2013-06-03 trunk 41049) [x86_64-freebsd9.1]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN
r41041 で、ブロック呼び出し前の VM 内の処理中に Ruby のメソッドが何らかの理由で呼ばれると argv
が壊れるという問題を直しました。
具体的には、
y = Object.new
def y.s(a)
yield(a)
end
m = Object.new
def m.method_missing(*a)
super
end
assert_equal [m, nil], y.s(m){|a,b|[a,b]}
のようなコードの場合、
- y.s に m と block が渡される
- y.s で yield(a) が呼ばれる
- argvが設定される
- vm_invoke_block 内の VALUE * const rsp = GET_SP() - ci->argc;
SET_SP(rsp); で argv の先頭に sp が設定される
- vm_yield_setup_args
- vm_yield_setup_block_args
- y.s のブロックパラメータは2つなのに、引数は一つなので、a.to_ary が呼ばれる
(rb_check_array_type(arg0))
- method_missing が呼ばれる
- super が呼ばれる (このへんで vm _push_frame が呼ばれる)
- vm_push_frameのinitialize local variablesのところでargvにnilが代入されて破壊される
で、これ自体は argv を対比しておいて戻せばよいです。
また、SET_SP(rsp)のあたりは、ささださん曰く「 argv に書き込みがない、という前提でそこは作ってるんだよね」だそうな。
しかし、「そんな前提わかるかっ」ですし、
methodの方は SAVE_RESTORE_CI(tmp = rb_check_convert_type(ary, T_ARRAY,
“Array”, “to_a”), ci); ともうちょっとわかりやすく書いてあるので、
「頂いた問題点を元に、一度全部総点検が必要そうです」とのことですので、お願いします。
Issue #8484 has been updated by Hiroshi SHIBATA.
Target version changed from 2.1.0 to current: 2.2.0
Bug #8484: Restoring conditions through the ruby method call during VM
processing
- Author: Yui NARUSE
- Status: Assigned
- Priority: Normal
- Assignee: Koichi Sasada
- Category: YARV
- Target version: current: 2.2.0
- ruby -v: ruby 2.1.0dev (2013-06-03 trunk 41049) [x86_64-freebsd9.1]
- Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN
r41041 で、ブロック呼び出し前の VM 内の処理中に Ruby のメソッドが何らかの理由で呼ばれると argv
が壊れるという問題を直しました。
具体的には、
y = Object.new
def y.s(a)
yield(a)
end
m = Object.new
def m.method_missing(*a)
super
end
assert_equal [m, nil], y.s(m){|a,b|[a,b]}
のようなコードの場合、
- y.s に m と block が渡される
- y.s で yield(a) が呼ばれる
- argvが設定される
- vm_invoke_block 内の VALUE * const rsp = GET_SP() - ci->argc;
SET_SP(rsp); で argv の先頭に sp が設定される
- vm_yield_setup_args
- vm_yield_setup_block_args
- y.s のブロックパラメータは2つなのに、引数は一つなので、a.to_ary が呼ばれる
(rb_check_array_type(arg0))
- method_missing が呼ばれる
- super が呼ばれる (このへんで vm _push_frame が呼ばれる)
- vm_push_frameのinitialize local variablesのところでargvにnilが代入されて破壊される
で、これ自体は argv を対比しておいて戻せばよいです。
また、SET_SP(rsp)のあたりは、ささださん曰く「 argv に書き込みがない、という前提でそこは作ってるんだよね」だそうな。
しかし、「そんな前提わかるかっ」ですし、
methodの方は SAVE_RESTORE_CI(tmp = rb_check_convert_type(ary, T_ARRAY,
“Array”, “to_a”), ci); ともうちょっとわかりやすく書いてあるので、
「頂いた問題点を元に、一度全部総点検が必要そうです」とのことですので、お願いします。
Issue #8484 has been updated by Nobuyoshi N…
Description updated
Bug #8484: Restoring conditions through the ruby method call during VM
processing
- Author: Yui NARUSE
- Status: Assigned
- Priority: Normal
- Assignee: Koichi Sasada
- Category: YARV
- Target version: current: 2.2.0
- ruby -v: ruby 2.1.0dev (2013-06-03 trunk 41049) [x86_64-freebsd9.1]
- Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN
r41041 で、ブロック呼び出し前の VM 内の処理中に Ruby のメソッドが何らかの理由で呼ばれると argv
が壊れるという問題を直しました。
具体的には、
y = Object.new
def y.s(a)
yield(a)
end
m = Object.new
def m.method_missing(*a)
super
end
assert_equal [m, nil], y.s(m){|a,b|[a,b]}
のようなコードの場合、
-
y.s
に m
と block
が渡される
-
y.s
で yield(a)
が呼ばれる
-
argv
が設定される
-
vm_invoke_block
内の VALUE * const rsp = GET_SP() - ci->argc; SET_SP(rsp);
で argv
の先頭に sp
が設定される
vm_yield_setup_args
vm_yield_setup_block_args
-
y.s
のブロックパラメータは2つなのに、引数は一つなので、a.to_ary
が呼ばれる
(rb_check_array_type(arg0)
)
-
method_missing
が呼ばれる
-
super
が呼ばれる (このへんで vm _push_frame
が呼ばれる)
-
vm_push_frame
のinitialize local variablesのところでargv
にnil
が代入されて破壊される
で、これ自体は argv
を対比しておいて戻せばよいです。
また、SET_SP(rsp)
のあたりは、ささださん曰く「 argv
に書き込みがない、という前提でそこは作ってるんだよね」だそうな。
しかし、「そんな前提わかるかっ」ですし、
methodの方は SAVE_RESTORE_CI(tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a"), ci);
ともうちょっとわかりやすく書いてあるので、
「頂いた問題点を元に、一度全部総点検が必要そうです」とのことですので、お願いします。