[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]