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