ruby-changes:36788
From: normal <ko1@a...>
Date: Wed, 17 Dec 2014 09:54:34 +0900 (JST)
Subject: [ruby-changes:36788] normal:r48869 (trunk): compile.c: skip opt_* insns for fstr args with block given
normal 2014-12-17 09:54:13 +0900 (Wed, 17 Dec 2014) New Revision: 48869 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48869 Log: compile.c: skip opt_* insns for fstr args with block given * compile.c (iseq_compile_each): only emit opt_str_freeze, opt_aref_with, and opt_aset_with insn when no block is given [Bug #10557] [ruby-core:66595] * test/ruby/test_optimization.rb (test_block_given_aset_aref): new test for bug thanks to Bartosz Kopinski. (test_string_freeze): additional assertion for object_id Modified files: trunk/ChangeLog trunk/compile.c trunk/test/ruby/test_optimization.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 48868) +++ ChangeLog (revision 48869) @@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Dec 17 09:48:57 2014 Eric Wong <e@8...> + + * compile.c (iseq_compile_each): only emit opt_str_freeze, + opt_aref_with, and opt_aset_with insn when no block is given + [Bug #10557] [ruby-core:66595] + * test/ruby/test_optimization.rb (test_block_given_aset_aref): + new test for bug thanks to Bartosz Kopinski. + (test_string_freeze): additional assertion for object_id + Wed Dec 17 01:06:47 2014 NAKAMURA Usaku <usa@r...> * ext/win32/lib/Win32API.rb (Win32API#call): need to splat. hmm, when Index: compile.c =================================================================== --- compile.c (revision 48868) +++ compile.c (revision 48869) @@ -4405,7 +4405,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4405 * "literal".freeze -> opt_str_freeze("literal") */ if (node->nd_recv && nd_type(node->nd_recv) == NODE_STR && - node->nd_mid == idFreeze && node->nd_args == NULL) + node->nd_mid == idFreeze && node->nd_args == NULL && + iseq->compile_data->current_block == Qfalse) { VALUE str = rb_fstring(node->nd_recv->nd_lit); iseq_add_mark_object(iseq, str); @@ -4420,7 +4421,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4421 */ if (node->nd_mid == idAREF && !private_recv_p(node) && node->nd_args && nd_type(node->nd_args) == NODE_ARRAY && node->nd_args->nd_alen == 1 && - nd_type(node->nd_args->nd_head) == NODE_STR) + nd_type(node->nd_args->nd_head) == NODE_STR && + iseq->compile_data->current_block == Qfalse) { VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit); node->nd_args->nd_head->nd_lit = str; @@ -5416,7 +5418,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L5418 */ if (node->nd_mid == idASET && !private_recv_p(node) && node->nd_args && nd_type(node->nd_args) == NODE_ARRAY && node->nd_args->nd_alen == 2 && - nd_type(node->nd_args->nd_head) == NODE_STR) + nd_type(node->nd_args->nd_head) == NODE_STR && + iseq->compile_data->current_block == Qfalse) { VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit); node->nd_args->nd_head->nd_lit = str; Index: test/ruby/test_optimization.rb =================================================================== --- test/ruby/test_optimization.rb (revision 48868) +++ test/ruby/test_optimization.rb (revision 48869) @@ -118,6 +118,7 @@ class TestRubyOptimization < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/ruby/test_optimization.rb#L118 def test_string_freeze assert_equal "foo", "foo".freeze + assert_equal "foo".freeze.object_id, "foo".freeze.object_id assert_redefine_method('String', 'freeze', 'assert_nil "foo".freeze') end @@ -253,4 +254,39 @@ class TestRubyOptimization < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/ruby/test_optimization.rb#L254 EOF assert_equal(123, delay { 123 }.call, bug6901) end + + class Bug10557 + def [](_) + block_given? + end + + def []=(_, _) + block_given? + end + end + + def test_block_given_aset_aref + bug10557 = '[ruby-core:66595]' + assert_equal(true, Bug10557.new.[](nil){}, bug10557) + assert_equal(true, Bug10557.new.[](0){}, bug10557) + assert_equal(true, Bug10557.new.[](false){}, bug10557) + assert_equal(true, Bug10557.new.[](''){}, bug10557) + assert_equal(true, Bug10557.new.[]=(nil, 1){}, bug10557) + assert_equal(true, Bug10557.new.[]=(0, 1){}, bug10557) + assert_equal(true, Bug10557.new.[]=(false, 1){}, bug10557) + assert_equal(true, Bug10557.new.[]=('', 1){}, bug10557) + end + + def test_string_freeze_block + assert_separately([], <<-"end;")# do + class String + undef freeze + def freeze + block_given? + end + end + assert_equal(true, "block".freeze {}) + assert_equal(false, "block".freeze) + end; + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/