1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
normal 2015-12-07 23:56:57 +00:00
parent d0ea0389e4
commit 4d2ce0cbff
3 changed files with 48 additions and 0 deletions

View file

@ -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.

View file

@ -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;

View file

@ -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