Skip to content

Commit

Permalink
Better handling of CGlobal & :call unnesting (#456)
Browse files Browse the repository at this point in the history
This supports SSAValue args for cglobal while also fixing a bug
in which a GotoIfNot ended up going to the wrong statement.
The latter was a consequence of incorrect :call unnesting.

Fixes #455
Fixes #454
Fixes #415
Fixes JuliaDebug/Debugger.jl#275
Improves #354
  • Loading branch information
timholy authored Dec 17, 2020
1 parent fc3b614 commit a7a65c2
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
- windows-latest
arch:
- x64
env:
PYTHON: ""
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
Expand Down
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ julia = "1"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Mmap = "a63ad114-7e13-5084-954f-fe012c677804"
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
TableReader = "70df011a-6618-58d7-8e16-3cf9e384cb47"
Tensors = "48a634ad-e948-5137-8d70-aa71f2a747f4"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "Dates", "Distributed", "LinearAlgebra", "Mmap", "SHA", "SparseArrays", "Tensors", "TableReader", "DataFrames"]
test = ["Test", "Dates", "Distributed", "HTTP", "LinearAlgebra", "Mmap", "PyCall", "SHA", "SparseArrays", "Tensors", "TableReader", "DataFrames"]
5 changes: 5 additions & 0 deletions src/builtins.jl
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,14 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool)
# Intrinsics
elseif f === Base.cglobal
if nargs == 1
call_expr = copy(call_expr)
args2 = args[2]
call_expr.args[2] = isa(args2, QuoteNode) ? args2 : @lookup(frame, args2)
return Some{Any}(Core.eval(moduleof(frame), call_expr))
elseif nargs == 2
call_expr = copy(call_expr)
args2 = args[2]
call_expr.args[2] = isa(args2, QuoteNode) ? args2 : @lookup(frame, args2)
call_expr.args[3] = @lookup(frame, args[3])
return Some{Any}(Core.eval(moduleof(frame), call_expr))
end
Expand Down
12 changes: 9 additions & 3 deletions src/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,30 @@ function replace_ssa!(stmt, ssalookup)
end

function renumber_ssa!(stmts::Vector{Any}, ssalookup)
# When updating jumps, when lines get split into multiple lines
# (see "Un-nest :call expressions" below), we need to jump to the first of them.
# Consequently we use the previous "old-code" offset and add one.
# Fixes #455.
jumplookup(l, idx) = idx > 1 ? l[idx-1] + 1 : idx

for (i, stmt) in enumerate(stmts)
if isa(stmt, GotoNode)
stmts[i] = GotoNode(ssalookup[stmt.label])
stmts[i] = GotoNode(jumplookup(ssalookup, stmt.label))
elseif isa(stmt, SSAValue)
stmts[i] = SSAValue(ssalookup[stmt.id])
elseif isa(stmt, NewSSAValue)
stmts[i] = SSAValue(stmt.id)
elseif isa(stmt, Expr)
replace_ssa!(stmt, ssalookup)
if (stmt.head === :gotoifnot || stmt.head === :enter) && isa(stmt.args[end], Int)
stmt.args[end] = ssalookup[stmt.args[end]]
stmt.args[end] = jumplookup(ssalookup, stmt.args[end])
end
elseif is_GotoIfNot(stmt)
cond = stmt.cond
if isa(cond, SSAValue)
cond = SSAValue(ssalookup[cond.id])
end
stmts[i] = Core.GotoIfNot(cond, ssalookup[stmt.dest])
stmts[i] = Core.GotoIfNot(cond, jumplookup(ssalookup, stmt.dest))
elseif is_ReturnNode(stmt)
val = (stmt::Core.ReturnNode).val
if isa(val, SSAValue)
Expand Down
10 changes: 10 additions & 0 deletions test/interpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,16 @@ val = @interpret(BigInt())
@test isa(val, BigInt) && val == 0
@test isa(@interpret(Base.GMP.version()), VersionNumber)

# Issue #455
using PyCall
let np = pyimport("numpy")
@test @interpret(PyCall.pystring_query(np.zeros)) === Union{}
end
# Issue #354 (partial fix)
using HTTP
headers = Dict("User-Agent" => "Debugger.jl")
@test_broken @interpret(HTTP.request("GET", "https://api.github.com/", headers))

# "correct" line numbers
defline = @__LINE__() + 1
function f(x)
Expand Down

0 comments on commit a7a65c2

Please sign in to comment.