def process_cdp args
type = args.shift
req = args.shift
case type
when :backtrace
exception = nil
result = {
reason: 'other',
callFrames: @target_frames.map.with_index{|frame, i|
exception = frame.raised_exception if frame == current_frame && frame.has_raised_exception
path = frame.realpath || frame.path
if frame.iseq.nil?
lineno = 0
else
lineno = frame.iseq.first_line - 1
end
{
callFrameId: SecureRandom.hex(16),
functionName: frame.name,
functionLocation: {
# scriptId: N, # filled by SESSION
lineNumber: lineno
},
location: {
# scriptId: N, # filled by SESSION
lineNumber: frame.location.lineno - 1 # The line number is 0-based.
},
url: path,
scopeChain: [
{
type: 'local',
object: {
type: 'object',
objectId: rand.to_s
}
},
{
type: 'script',
object: {
type: 'object',
objectId: rand.to_s
}
},
{
type: 'global',
object: {
type: 'object',
objectId: rand.to_s
}
}
],
this: {
type: 'object'
}
}
}
}
if exception
result[:data] = evaluate_result exception
result[:reason] = 'exception'
end
event! :protocol_result, :backtrace, req, result
when :evaluate
res = {}
fid, expr, group = args
frame = @target_frames[fid]
message = nil
if frame && (b = frame.eval_binding)
special_local_variables frame do |name, var|
b.local_variable_set(name, var) if /\%/ !~name
end
result = nil
case group
when 'popover'
case expr
# Chrome doesn't read instance variables
when /\A\$\S/
safe_global_variables.each{|gvar|
if gvar.to_s == expr
result = eval(gvar.to_s)
break false
end
} and (message = "Error: Not defined global variable: #{expr.inspect}")
when /(\A((::[A-Z]|[A-Z])\w*)+)/
unless result = search_const(b, $1)
message = "Error: Not defined constant: #{expr.inspect}"
end
else
begin
result = b.local_variable_get(expr)
rescue NameError
# try to check method
if M_RESPOND_TO_P.bind_call(b.receiver, expr, include_all: true)
result = M_METHOD.bind_call(b.receiver, expr)
else
message = "Error: Can not evaluate: #{expr.inspect}"
end
end
end
when 'console', 'watch-group'
begin
orig_stdout = $stdout
$stdout = StringIO.new
result = b.eval(expr.to_s, '(DEBUG CONSOLE)')
rescue Exception => e
result = e
res[:exceptionDetails] = exceptionDetails(e, 'Uncaught')
ensure
output = $stdout.string
$stdout = orig_stdout
end
else
message = "Error: unknown objectGroup: #{group}"
end
else
result = Exception.new("Error: Can not evaluate on this frame")
end
res[:result] = evaluate_result(result)
event! :protocol_result, :evaluate, req, message: message, response: res, output: output
when :scope
fid = args.shift
frame = @target_frames[fid]
if b = frame.binding
vars = b.local_variables.map{|name|
v = b.local_variable_get(name)
variable(name, v)
}
special_local_variables frame do |name, val|
vars.unshift variable(name, val)
end
vars.unshift variable('%self', b.receiver)
elsif lvars = frame.local_variables
vars = lvars.map{|var, val|
variable(var, val)
}
else
vars = [variable('%self', frame.self)]
special_local_variables frame do |name, val|
vars.unshift variable(name, val)
end
end
event! :protocol_result, :scope, req, vars
when :properties
oid = args.shift
result = []
prop = []
if obj = @obj_map[oid]
case obj
when Array
result = obj.map.with_index{|o, i|
variable i.to_s, o
}
when Hash
result = obj.map{|k, v|
variable(k, v)
}
when Struct
result = obj.members.map{|m|
variable(m, obj[m])
}
when String
prop = [
internalProperty('#length', obj.length),
internalProperty('#encoding', obj.encoding)
]
when Class, Module
result = obj.instance_variables.map{|iv|
variable(iv, obj.instance_variable_get(iv))
}
prop = [internalProperty('%ancestors', obj.ancestors[1..])]
when Range
prop = [
internalProperty('#begin', obj.begin),
internalProperty('#end', obj.end),
]
end
result += M_INSTANCE_VARIABLES.bind_call(obj).map{|iv|
variable(iv, M_INSTANCE_VARIABLE_GET.bind_call(obj, iv))
}
prop += [internalProperty('#class', M_CLASS.bind_call(obj))]
end
event! :protocol_result, :properties, req, result: result, internalProperties: prop
when :exception
oid = args.shift
exc = nil
if obj = @obj_map[oid]
exc = exceptionDetails obj, obj.to_s
end
event! :protocol_result, :exception, req, exceptionDetails: exc
end
end