Class: Rubinius::Debugger::Command::Next

Inherits:
Rubinius::Debugger::Command show all
Defined in:
lib/rubinius/debugger/commands.rb

Direct Known Subclasses

NextInstruction, StepInto

Instance Method Summary collapse

Methods inherited from Rubinius::Debugger::Command

commands, #current_frame, #current_method, descriptor, ext_help, help, #initialize, #listen, match?, pattern, #run_code, #variables

Methods included from Display

#ask, #crit, #display, #error, #info, #section

Constructor Details

This class inherits a constructor from Rubinius::Debugger::Command

Instance Method Details

#goto_between(exec, start, fin) ⇒ Object



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/rubinius/debugger/commands.rb', line 317

def goto_between(exec, start, fin)
  goto = Rubinius::InstructionSet.opcodes_map[:goto]
  git  = Rubinius::InstructionSet.opcodes_map[:goto_if_true]
  gif  = Rubinius::InstructionSet.opcodes_map[:goto_if_false]

  iseq = exec.iseq

  i = start
  while i < fin
    op = iseq[i]
    case op
    when goto
      return next_interesting(exec, iseq[i + 1]) # goto target
    when git, gif
      return [next_interesting(exec, iseq[i + 1]),
        next_interesting(exec, i + 2)] # target and next ip
    else
      op = Rubinius::InstructionSet[op]
      i += (op.arg_count + 1)
    end
  end

  return next_interesting(exec, fin)
end

#next_interesting(exec, ip) ⇒ Object



307
308
309
310
311
312
313
314
315
# File 'lib/rubinius/debugger/commands.rb', line 307

def next_interesting(exec, ip)
  pop = Rubinius::InstructionSet.opcodes_map[:pop]

  if exec.iseq[ip] == pop
    return ip + 1
  end

  return ip
end

#run(args) ⇒ Object



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/rubinius/debugger/commands.rb', line 225

def run(args)
  if !args or args.empty?
    step = 1
  else
    step = args.to_i
  end

  if step <= 0
    error "Invalid step count - #{step}"
    return
  end

  step_over_by(step)
  @debugger.listen
end

#set_breakpoints_between(exec, start_ip, fin_ip) ⇒ Object



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/rubinius/debugger/commands.rb', line 274

def set_breakpoints_between(exec, start_ip, fin_ip)
  ips = goto_between(exec, start_ip, fin_ip)
  if ips.kind_of? Fixnum
    ip = ips
  else
    one, two = ips
    bp1 = BreakPoint.for_ip(exec, one)
    bp2 = BreakPoint.for_ip(exec, two)

    bp1.paired_with(bp2)
    bp2.paired_with(bp1)

    bp1.for_step!(current_frame.variables)
    bp2.for_step!(current_frame.variables)

    bp1.activate
    bp2.activate

    return bp1
  end

  if ip == -1
    error "No place to step to"
    return nil
  end

  bp = BreakPoint.for_ip(exec, ip)
  bp.for_step!(current_frame.variables)
  bp.activate

  return bp
end

#step_over_by(step) ⇒ Object



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/rubinius/debugger/commands.rb', line 241

def step_over_by(step)
  f = current_frame

  ip = -1

  exec = f.method
  possible_line = f.line + step
  fin_ip = exec.first_ip_on_line possible_line, f.ip

  if !fin_ip
    return step_to_parent
  end

  set_breakpoints_between(exec, f.ip, fin_ip)
end

#step_to_parentObject



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/rubinius/debugger/commands.rb', line 257

def step_to_parent
  f = @debugger.frame(current_frame.number + 1)
  unless f
    info "Unable to find frame to step to next"
    return
  end

  exec = f.method
  ip = f.ip

  bp = BreakPoint.for_ip(exec, ip)
  bp.for_step!(f.variables)
  bp.activate

  return bp
end