From 4d1ffcce8acb35e5aec263d64d5c88a8434b1c64 Mon Sep 17 00:00:00 2001 From: yui-knk Date: Sun, 24 Dec 2017 01:13:44 +0900 Subject: [PATCH] Fix how to detect potential_lines On Ruby 2.5, format of `RubyVM::InstructionSequence#disasm` will be changed. By this change we can not detect which line is valid to set breakpoints. On the other hand Ruby 2.5 will introduce new methods * `RubyVM::InstructionSequence#each_child` Iterate all direct child instruction sequences. * `RubyVM::InstructionSequence#trace_points` Return trace points in the instruction sequence. see: https://github.com/ruby/ruby/blob/9fe26ef8de1ae047a4d775ce74878a0aeb01a19b/NEWS We can detect potential_lines by these methods. So this commit defines new methods and call each_child & trace_points if these methods are implemented. Thanks to Koichi Sasada (ko1) for investigation, implemention of new methods for Ruby and concept implementation for byebug. --- lib/byebug/breakpoint.rb | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/byebug/breakpoint.rb b/lib/byebug/breakpoint.rb index 5a17d5e45..b1d14b47c 100644 --- a/lib/byebug/breakpoint.rb +++ b/lib/byebug/breakpoint.rb @@ -49,9 +49,27 @@ def self.remove(id) # def self.potential_lines(filename) name = "#{Time.new.to_i}_#{rand(2**31)}" - lines = {} iseq = RubyVM::InstructionSequence.compile(File.read(filename), name) + if iseq.respond_to?(:each_child) + potential_lines_with_trace_points(iseq, {}) + else + potential_lines_without_trace_points(iseq, {}) + end + end + + def self.potential_lines_with_trace_points(iseq, lines) + iseq.trace_points.each { |(line, _)| lines[line] = true } + iseq.each_child do |child| + potential_lines_with_trace_points(child, lines) + end + + lines.keys.sort + end + + private_class_method :potential_lines_with_trace_points + + def self.potential_lines_without_trace_points(iseq, lines) iseq.disasm.each_line do |line| res = /^\d+ (?\w+)\s+.+\(\s*(?\d+)\)$/.match(line) next unless res && res[:insn] == 'trace' @@ -62,6 +80,8 @@ def self.potential_lines(filename) lines.keys end + private_class_method :potential_lines_without_trace_points + # # Returns true if a breakpoint could be set in line number +lineno+ in file # name +filename.