ruby-changes:37420
From: marcandre <ko1@a...>
Date: Thu, 5 Feb 2015 04:10:13 +0900 (JST)
Subject: [ruby-changes:37420] marcandRe: r49501 (trunk): * vm_eval.c: Fix symbol leak with non optimized +send+ and method_missing [#10828]
marcandre 2015-02-05 04:10:03 +0900 (Thu, 05 Feb 2015) New Revision: 49501 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=49501 Log: * vm_eval.c: Fix symbol leak with non optimized +send+ and method_missing [#10828] Modified files: trunk/test/ruby/test_symbol.rb trunk/vm_eval.c Index: vm_eval.c =================================================================== --- vm_eval.c (revision 49500) +++ vm_eval.c (revision 49501) @@ -884,16 +884,18 @@ send_internal(int argc, const VALUE *arg https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L884 rb_raise(rb_eArgError, "no method name given"); } - vid = *argv++; argc--; + vid = *argv; id = rb_check_id(&vid); if (!id) { if (rb_method_basic_definition_p(CLASS_OF(recv), idMethodMissing)) { VALUE exc = make_no_method_exception(rb_eNoMethodError, NULL, - recv, ++argc, --argv); + recv, argc, argv); rb_exc_raise(exc); } - id = rb_to_id(vid); + id = idMethodMissing; + } else { + argv++; argc--; } PASS_PASSED_BLOCK_TH(th); return rb_call0(recv, id, argc, argv, scope, self); Index: test/ruby/test_symbol.rb =================================================================== --- test/ruby/test_symbol.rb (revision 49500) +++ test/ruby/test_symbol.rb (revision 49501) @@ -274,4 +274,33 @@ class TestSymbol < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_symbol.rb#L274 10.times { |i| x.send "send should not leak #{i} - sym mm".to_sym } end end + + def test_symbol_send_leak_string_no_optimization + assert_no_immortal_symbol_created do + 10.times { 42.method(:send).call "send should not leak #{i} - str slow" rescue nil } + end + end + + def test_symbol_send_leak_symbol_no_optimization + assert_no_immortal_symbol_created do + 10.times { 42.method(:send).call "send should not leak #{i} - sym slow".to_sym rescue nil } + end + end + + def test_symbol_send_leak_string_custom_method_missing_no_optimization + x = Object.new + def x.method_missing(*); end + assert_no_immortal_symbol_created do + 10.times { |i| x.method(:send).call "send should not leak #{i} - str mm slow" } + end + end + + def test_symbol_send_leak_symbol_custom_method_missing_no_optimization + x = Object.new + def x.method_missing(*); end + assert_no_immortal_symbol_created do + 10.times { |i| x.method(:send).call "send should not leak #{i} - sym mm slow".to_sym } + end + end + end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/