aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-17 00:54:13 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-17 00:54:13 +0000
commitfcf6fa8781fe236a9761ad5d75fa1b87f1afeea2 (patch)
treef0f172234f2556eee22e11e59b8e99f6068d6cc8
parent61a8e7ebf76a1564df17ea4de4fe4ce21dba28f8 (diff)
downloadruby-fcf6fa8781fe236a9761ad5d75fa1b87f1afeea2.tar.gz
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 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48869 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog9
-rw-r--r--compile.c9
-rw-r--r--test/ruby/test_optimization.rb36
3 files changed, 51 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 6caf3c04eb..5e423d37cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Wed Dec 17 09:48:57 2014 Eric Wong <e@80x24.org>
+
+ * 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@ruby-lang.org>
* ext/win32/lib/Win32API.rb (Win32API#call): need to splat. hmm, when
diff --git a/compile.c b/compile.c
index 6c6d933223..8672c0e980 100644
--- a/compile.c
+++ b/compile.c
@@ -4405,7 +4405,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
* "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_ANCHOR *ret, NODE * node, int poped)
*/
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_ANCHOR *ret, NODE * node, int poped)
*/
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;
diff --git a/test/ruby/test_optimization.rb b/test/ruby/test_optimization.rb
index 129f62a0ff..4a5484e43d 100644
--- a/test/ruby/test_optimization.rb
+++ b/test/ruby/test_optimization.rb
@@ -118,6 +118,7 @@ class TestRubyOptimization < Test::Unit::TestCase
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::TestCase
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