Feature #13355 ยป 0001-compile.c-optimize-literal-String-range-in-case-when.patch
compile.c | ||
---|---|---|
}
|
||
}
|
||
/*
|
||
* putstring "beg"
|
||
* putstring "end"
|
||
* newrange excl
|
||
*
|
||
* ==>
|
||
*
|
||
* putobject "beg".."end"
|
||
*/
|
||
if (IS_INSN_ID(iobj, checkmatch)) {
|
||
INSN *range = (INSN *)get_prev_insn(iobj);
|
||
INSN *beg, *end;
|
||
if (range && IS_INSN_ID(range, newrange) &&
|
||
(end = (INSN *)get_prev_insn(range)) != 0 &&
|
||
IS_INSN_ID(end, putstring) &&
|
||
(beg = (INSN *)get_prev_insn(end)) != 0 &&
|
||
IS_INSN_ID(beg, putstring)) {
|
||
VALUE sbeg = OPERAND_AT(beg, 0);
|
||
VALUE send = OPERAND_AT(end, 0);
|
||
int excl = FIX2INT(OPERAND_AT(range, 0));
|
||
VALUE lit_range = rb_range_new(sbeg, send, excl);
|
||
iseq_add_mark_object_compile_time(iseq, lit_range);
|
||
REMOVE_ELEM(&beg->link);
|
||
REMOVE_ELEM(&end->link);
|
||
range->insn_id = BIN(putobject);
|
||
OPERAND_AT(range, 0) = lit_range;
|
||
}
|
||
}
|
||
if (IS_INSN_ID(iobj, leave)) {
|
||
remove_unreachable_chunk(iseq, iobj->link.next);
|
||
}
|
test/ruby/test_optimization.rb | ||
---|---|---|
bug11816 = '[ruby-core:74993] [Bug #11816]'
|
||
assert_ruby_status([], 'nil&.foo &&= false', bug11816)
|
||
end
|
||
def test_peephole_string_literal_range
|
||
code = <<-EOF
|
||
case ver
|
||
when "2.0.0".."2.3.2" then :foo
|
||
when "1.8.0"..."1.8.8" then :bar
|
||
end
|
||
EOF
|
||
iseq = RubyVM::InstructionSequence.compile(code)
|
||
insn = iseq.disasm
|
||
assert_match %r{putobject\s+#{Regexp.quote('"1.8.0"..."1.8.8"')}}, insn
|
||
assert_match %r{putobject\s+#{Regexp.quote('"2.0.0".."2.3.2"')}}, insn
|
||
assert_no_match /putstring/, insn
|
||
assert_no_match /newrange/, insn
|
||
end
|
||
end
|
||
-
|