summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-07 23:56:57 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-07 23:56:57 +0000
commit4d2ce0cbff3cee1119fb664bca5f67332a94dadd (patch)
treedde3df024ecab3b972b8cd058dee64d0b292df6f
parentd0ea0389e4bfcb09a670ef307b90af16db0777ee (diff)
insns.def (opt_case_dispatch): check Float#=== redefinition
The missing check for Float#=== redefinition was noticed while working on enhancing optimized case dispatch for nil/true/false in [ruby-core:71818] https://bugs.ruby-lang.org/issues/11769 So no, I don't normally redefine core classes like this :P * insns.def (opt_case_dispatch): check Float#=== redefinition * test/ruby/test_optimization.rb (test_opt_case_dispatch): new [ruby-core:71920] [Bug #11784] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52928 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--insns.def1
-rw-r--r--test/ruby/test_optimization.rb41
3 files changed, 48 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 0b2c00d92d..f3cf0bc332 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Tue Dec 8 08:56:16 2015 Eric Wong <e@80x24.org>
+
+ * insns.def (opt_case_dispatch): check Float#=== redefinition
+ * test/ruby/test_optimization.rb (test_opt_case_dispatch): new
+ [ruby-core:71920] [Bug #11784]
+
Tue Dec 8 03:56:05 2015 Koichi Sasada <ko1@atdot.net>
* test/lib/iseq_loader_checker.rb: add iseq dumper/loader checker.
diff --git a/insns.def b/insns.def
index 36a132b585..c8088919c5 100644
--- a/insns.def
+++ b/insns.def
@@ -1271,6 +1271,7 @@ opt_case_dispatch
if (BASIC_OP_UNREDEFINED_P(BOP_EQQ,
SYMBOL_REDEFINED_OP_FLAG |
FIXNUM_REDEFINED_OP_FLAG |
+ FLOAT_REDEFINED_OP_FLAG |
BIGNUM_REDEFINED_OP_FLAG |
STRING_REDEFINED_OP_FLAG)) {
st_data_t val;
diff --git a/test/ruby/test_optimization.rb b/test/ruby/test_optimization.rb
index e2efc9d11c..23c522612f 100644
--- a/test/ruby/test_optimization.rb
+++ b/test/ruby/test_optimization.rb
@@ -308,4 +308,45 @@ class TestRubyOptimization < Test::Unit::TestCase
assert_equal(false, "block".freeze)
end;
end
+
+ def test_opt_case_dispatch
+ code = <<-EOF
+ case foo
+ when "foo" then :foo
+ when :sym then :sym
+ when 6 then :fix
+ when 0.1 then :float
+ when 0xffffffffffffffff then :big
+ else
+ :nomatch
+ end
+ EOF
+ check = {
+ 'foo' => :foo,
+ :sym => :sym,
+ 6 => :fix,
+ 0.1 => :float,
+ 0xffffffffffffffff => :big,
+ }
+ iseq = RubyVM::InstructionSequence.compile(code)
+ assert_match %r{\bopt_case_dispatch\b}, iseq.disasm
+ check.each do |foo, expect|
+ assert_equal expect, eval("foo = #{foo.inspect}\n#{code}")
+ end
+ assert_equal :nomatch, eval("foo = :blah\n#{code}")
+ check.each do |foo, _|
+ klass = foo.class.to_s
+ assert_separately([], <<-"end;") # do
+ class #{klass}
+ undef ===
+ def ===(*args)
+ false
+ end
+ end
+ foo = #{foo.inspect}
+ ret = #{code}
+ assert_equal :nomatch, ret, foo.inspect
+ end;
+ end
+ end
end