Bug #8484

Restoring conditions through the ruby method call during VM processing

Added by Yui NARUSE almost 2 years ago. Updated 11 months ago.

[ruby-dev:47393]
Status:Assigned
Priority:Normal
Assignee:Koichi Sasada
ruby -v:ruby 2.1.0dev (2013-06-03 trunk 41049) [x86_64-freebsd9.1] Backport:1.9.3: UNKNOWN, 2.0.0: UNKNOWN

Description

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.smblock が渡される
* y.syield(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のところでargvnilが代入されて破壊される

で、これ自体は argv を対比しておいて戻せばよいです。
また、SET_SP(rsp)のあたりは、ささださん曰く「 argv に書き込みがない、という前提でそこは作ってるんだよね」だそうな。
しかし、「そんな前提わかるかっ」ですし、
methodの方は SAVE_RESTORE_CI(tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a"), ci); ともうちょっとわかりやすく書いてあるので、
「頂いた問題点を元に、一度全部総点検が必要そうです」とのことですので、お願いします。

History

#1 Updated by Hiroshi SHIBATA about 1 year ago

  • Target version changed from 2.1.0 to current: 2.2.0

#2 Updated by Nobuyoshi Nakada 11 months ago

  • Description updated (diff)

Also available in: Atom PDF