Module: Trepanning::Method

Defined in:
app/method.rb

Class Method Summary collapse

Class Method Details

.find_method_with_line(cm, line) ⇒ Object

Returns a CompiledMethod for the specified line. We search the current method meth and then up the parent scope. If we hit the top and we can’t find line that way, then we reverse the search from the top and search down. This will add all siblings of ancestors of meth.



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'app/method.rb', line 81

def find_method_with_line(cm, line)
  unless cm.kind_of?(Rubinius::CompiledMethod)
    return nil
  end
  
  lines = lines_of_method(cm)
  ## p ['++++1', cm, lines]
  return cm if lines.member?(line) 
  scope = cm.scope
  return nil unless scope.current_script
  cm  = scope.current_script.compiled_method
  lines = lines_of_method(cm)
  ## p ['++++2', cm, lines]
  until lines.member?(line) do
    child = scope
    scope = scope.parent
    unless scope
      # child is the top-most scope. Search down from here.
      cm = child.current_script.compiled_method
      pair = locate_line(line, cm)
      ## pair = cm.locate_line(line)
      return pair ? pair[0] : nil
    end
    cm = scope.current_script.compiled_method
    lines = lines_of_method(cm)
    ## p ['++++3', cm, lines]
  end
  return cm
end

.lines_of_method(cm) ⇒ Object



59
60
61
62
63
64
65
# File 'app/method.rb', line 59

def lines_of_method(cm)
  lines = []
  cm.lines.each_with_index do |l, i|
    lines << l if (i&1 == 1)
  end
  return lines
end

.locate_line(line, cm = self) ⇒ (Rubinius::CompiledMethod, Fixnum), NilClass

FIXME: Try using Routine in Rubinius now.

Locates the CompiledMethod and instruction address (IP) of the first instruction on the specified line. This method recursively examines child compiled methods until an exact match for the searched line is found. It returns both the matching CompiledMethod and the IP of the first instruction on the requested line, or nil if no match for the specified line is found.

Returns:

  • ((Rubinius::CompiledMethod, Fixnum), NilClass)

    returns nil if nothing is found, else an array of size 2 containing the method the line was found in and the IP pointing there.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'app/method.rb', line 41

def locate_line(line, cm=self)
  ## p [cm, lines_of_method(cm)]
  ip = locate_line_in_cm(line, cm)
  return cm, ip if ip

  # Didn't find line in this CM, so check if a contained
  # CM encompasses the line searched for
  cm.child_methods.each do |child|
    if res = locate_line(line, child)
      return res
    end
  end

  # No child method is a match - fail
  return nil
end

.locate_line_in_cm(line, cm = self) ⇒ Fixnum, NilClass

FIXME: until the next two routines find their way back into Rubinius::CompiledMethod…

Locates the instruction address (IP) of the first instruction on the specified line if is in CompiledMethod cm only, or nil if no match for the specified line is found.

Returns:

  • (Fixnum, NilClass)

    returns nil if nothing is found, else the first IP for the line



14
15
16
17
18
19
20
21
22
23
24
25
# File 'app/method.rb', line 14

def locate_line_in_cm(line, cm=self)
  cm.lines.each_with_index do |l, i|
    next unless (i&1 == 1)
    if (l ==  line)
      # Found target line - return first IP
      return cm.lines[i-1]
    elsif l > line
      return nil
    end
  end
  return nil
end

.valid_ip?(cm, ip) ⇒ Boolean

Return true if ip is the start of some instruction in meth. FIXME: be more stringent.

Returns:

  • (Boolean)


70
71
72
73
# File 'app/method.rb', line 70

def valid_ip?(cm, ip)
  size = cm.lines.size
  ip >= 0 && ip < cm.lines[size-1]
end