Skip to content

Commit

Permalink
some updates
Browse files Browse the repository at this point in the history
  • Loading branch information
KristofferC committed Apr 2, 2019
1 parent 4ea763d commit 4fc42cd
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 29 deletions.
43 changes: 21 additions & 22 deletions src/breakpoints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ end
function add_breakpoint_if_match!(framecode::FrameCode, bp::AbstractBreakpoint)
if framecode_matches_breakpoint(framecode, bp)
stmtidx = bp.line === 0 ? 1 : statementnumber(framecode, bp.line)
breakpoint!(framecode, stmtidx, bp.condition)
breakpoint!(framecode, stmtidx, bp.condition, bp.enabled[])
push!(bp.applications, BreakpointRef(framecode, stmtidx))
end
end
Expand All @@ -34,8 +34,7 @@ function framecode_matches_breakpoint(framecode::FrameCode, bp::BreakpointSignat
bp.f isa Method && return meth === bp.f
bp.f === extract_function_from_method(meth) || return false
bp.sig === nothing && return true
tt = Base.signature_type(bp.f, bp.sig)
return whichtt(tt) === meth
return bp.sig <: meth.sig
end

"""
Expand All @@ -61,11 +60,10 @@ breakpoint(radius2, Tuple{Int,Int}, :(y > x))
"""
function breakpoint(f, sig=nothing, line::Integer=0, condition::Condition=nothing)
sig !== nothing && (sig = Base.to_tuple_type(sig))
bp = BreakpointSignature(f, sig, line, condition, BreakpointRef[])
bp = BreakpointSignature(f, sig, line, condition, Ref(true), BreakpointRef[])
add_to_existing_framecodes(bp)
if !any(isequal(bp), _breakpoints)
push!(_breakpoints, bp)
end
idx = findfirst(bp2 -> same_location(bp, bp2), _breakpoints)
idx === nothing ? push!(_breakpoints, bp) : (_breakpoints[idx] = bp)
return bp
end
breakpoint(f, sig, condition::Condition) = breakpoint(f, sig, 0, condition)
Expand All @@ -83,11 +81,10 @@ function breakpoint(file::String, line::Integer=0, condition::Condition=nothing)
if maybe_source_file === nothing
file = abspath(file)
end
bp = BreakpointFileLocation(Symbol(file), line, condition, BreakpointRef[])
bp = BreakpointFileLocation(Symbol(file), line, condition, Ref(true), BreakpointRef[])
add_to_existing_framecodes(bp)
if !any(isequal(bp), _breakpoints)
push!(_breakpoints, bp)
end
idx = findfirst(bp2 -> same_location(bp, bp2), _breakpoints)
idx === nothing ? push!(_breakpoints, bp) : (_breakpoints[idx] = bp)
return bp
end

Expand Down Expand Up @@ -138,39 +135,41 @@ end
_unpack(condition) = isa(condition, Expr) ? (Main, condition) : condition

## The fundamental implementations of breakpoint-setting
function breakpoint!(framecode::FrameCode, pc, condition::Condition=nothing)
function breakpoint!(framecode::FrameCode, pc, condition::Condition=nothing, enabled=true)
stmtidx = pc
if condition === nothing
framecode.breakpoints[stmtidx] = BreakpointState()
framecode.breakpoints[stmtidx] = BreakpointState(enabled)
else
mod, cond = _unpack(condition)
fex = prepare_slotfunction(framecode, cond)
framecode.breakpoints[stmtidx] = BreakpointState(true, Core.eval(mod, fex))
framecode.breakpoints[stmtidx] = BreakpointState(enabled, Core.eval(mod, fex))
end
end
breakpoint!(frame::Frame, pc=frame.pc, condition::Condition=nothing) =
breakpoint!(frame.framecode, pc, condition)

update_states!(bp::AbstractBreakpoint) = foreach(bpref -> update_state!(bpref, bp.enabled[]), bp.applications)
update_state!(bp::BreakpointRef, v::Bool) = bp[] = v

"""
enable(bp::AbstractBreakpoint)
Enable breakpoint `bp`.
"""
enable(bp::AbstractBreakpoint) = foreach(enable, bp.applications)
enable(bp::BreakpointRef) = bp[] = true
enable(bp::AbstractBreakpoint) = (bp.enabled[] = true; update_states!(bp))
enable(bp::BreakpointRef) = bp[] = true


"""
disable(bp::BreakpointRef)
disable(bp::AbstractBreakpoint)
Disable breakpoint `bp`. Disabled breakpoints can be re-enabled with [`enable`](@ref).
"""
disable(bp::AbstractBreakpoint) = foreach(disable, bp.applications)
disable(bp::BreakpointRef) = bp[] = false

disable(bp::AbstractBreakpoint) = (bp.enabled[] = false; update_states!(bp))
disable(bp::BreakpointRef) = bp[] = false

"""
remove(bp::BreakpointRef)
remove(bp::AbstractBreakpoint)
Remove (delete) breakpoint `bp`. Removed breakpoints cannot be re-enabled.
"""
Expand All @@ -189,7 +188,7 @@ end
Toggle breakpoint `bp`.
"""
toggle(bp::AbstractBreakpoint) = foreach(toggle, bp.applications)
toggle(bp::AbstractBreakpoint) = (bp.enabled[] = !bp.enabled[]; update_states!(bp))
function toggle(bp::BreakpointRef)
state = bp[]
bp.framecode.breakpoints[bp.stmtidx] = BreakpointState(!state.isactive, state.condition)
Expand Down
18 changes: 14 additions & 4 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -275,15 +275,18 @@ const Condition = Union{Nothing,Expr,Tuple{Module,Expr}}

abstract type AbstractBreakpoint end

same_location(::AbstractBreakpoint, ::AbstractBreakpoint) = false

struct BreakpointSignature <: AbstractBreakpoint
f # Method or function
sig::Union{Nothing, Type}
line::Int # 0 is a sentinel for first statement
condition::Condition
enabled::Ref{Bool}
applications::Vector{BreakpointRef}
end
Base.isequal(bp2::BreakpointSignature, bp::BreakpointSignature) =
bp2.f == bp.f && bp2.sig == bp.sig && bp2.line == bp.line && bp.condition == bp2.condition
same_location(bp2::BreakpointSignature, bp::BreakpointSignature) =
bp2.f == bp.f && bp2.sig == bp.sig && bp2.line == bp.line
function Base.show(io::IO, bp::BreakpointSignature)
print(io, "BreakpointSignature: ")
print(io, bp.f)
Expand All @@ -296,21 +299,28 @@ function Base.show(io::IO, bp::BreakpointSignature)
if bp.condition !== nothing
print(io, " ", bp.condition)
end
if !bp.enabled[]
print(io, " [disabled]")
end
end

struct BreakpointFileLocation <: AbstractBreakpoint
file::Symbol
line::Integer
condition::Condition
enabled::Ref{Bool}
applications::Vector{BreakpointRef}
end
Base.isequal(bp2::BreakpointFileLocation, bp::BreakpointFileLocation) =
bp2.file == bp.line && bp2.line == bp.line && bp2.condition == bp.condition
same_location(bp2::BreakpointFileLocation, bp::BreakpointFileLocation) =
bp2.file == bp.line && bp2.line == bp.line
function Base.show(io::IO, bp::BreakpointFileLocation)
print(io, "BreakpointFileLocation: ")
print(io, bp.file, ':', bp.line)
if bp.condition !== nothing
print(io, bp.condition)
end
if !bp.enabled[]
print(io, " [disabled]")
end
end

21 changes: 18 additions & 3 deletions test/breakpoints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ struct Squarer end
# Conditional breakpoints on local variables
remove()
halfthresh = loop_radius2(5)
@breakpoint loop_radius2(10) 5 s>$halfthresh
frame, bp = @interpret loop_radius2(10)
@test isa(bp, JuliaInterpreter.BreakpointRef)
bp = @breakpoint loop_radius2(10) 5 s>$halfthresh
frame, bpref = @interpret loop_radius2(10)
@test isa(bpref, JuliaInterpreter.BreakpointRef)
lframe = leaf(frame)
s_extractor = eval(JuliaInterpreter.prepare_slotfunction(lframe.framecode, :s))
@test s_extractor(lframe) == loop_radius2(6)
Expand Down Expand Up @@ -234,3 +234,18 @@ end
if tmppath != ""
rm(tmppath)
end

remove()
f_break(x::Int) = x
bp = breakpoint(f_break)
frame, bpref = @interpret f_break(5)
@test bpref isa BreakpointRef
toggle(bp)
@test (@interpret f_break(5)) == 5
f_break(x::Float64) = 2x
@test (@interpret f_break(2.0)) == 4.0
toggle(bp)
frame, bpref = @interpret f_break(5)
@test bpref isa BreakpointRef
frame, bpref = @interpret f_break(2.0)
@test bpref isa BreakpointRef

0 comments on commit 4fc42cd

Please sign in to comment.