Skip to content

Commit

Permalink
Restore unnesting and use it in ccall. Fixes #8.
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy committed Feb 10, 2019
1 parent 4d11b77 commit a54761a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 23 deletions.
49 changes: 26 additions & 23 deletions src/JuliaInterpreter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -391,13 +391,16 @@ function copy_codeinfo(code::CodeInfo)
return newcode
end

const calllike = Set([:call, :struct_type])
const calllike = Set([:call, :foreigncall])

function extract_inner_call!(stmt, idx, once::Bool=false)
isa(stmt, Expr) || return nothing
once |= stmt.head calllike
for (i, a) in enumerate(stmt.args)
isa(a, Expr) || continue
if stmt.head == :foreigncall && i == 1
continue
end
ret = extract_inner_call!(a, idx, once) # doing this first extracts innermost calls
ret !== nothing && return ret
iscalllike = a.head calllike
Expand Down Expand Up @@ -488,28 +491,28 @@ function optimize!(code::CodeInfo, mod::Module)
end
end

# ## Un-nest :call expressions (so that there will be only one :call per line)
# # This will allow us to re-use args-buffers rather than having to allocate new ones each time.
# old_code, old_codelocs = code.code, code.codelocs
# code.code = new_code = eltype(old_code)[]
# code.codelocs = new_codelocs = Int32[]
# ssainc = fill(1, length(old_code))
# for (i, stmt) in enumerate(old_code)
# loc = old_codelocs[i]
# inner = extract_inner_call!(stmt, length(new_code)+1)
# while inner !== nothing
# push!(new_code, inner)
# push!(new_codelocs, loc)
# ssainc[i] += 1
# inner = extract_inner_call!(stmt, length(new_code)+1)
# end
# push!(new_code, stmt)
# push!(new_codelocs, loc)
# end
# # Fix all the SSAValues and GotoNodes
# ssalookup = cumsum(ssainc)
# renumber_ssa!(new_code, ssalookup)
# code.ssavaluetypes = length(new_code)
## Un-nest :call expressions (so that there will be only one :call per line)
# This will allow us to re-use args-buffers rather than having to allocate new ones each time.
old_code, old_codelocs = code.code, code.codelocs
code.code = new_code = eltype(old_code)[]
code.codelocs = new_codelocs = Int32[]
ssainc = fill(1, length(old_code))
for (i, stmt) in enumerate(old_code)
loc = old_codelocs[i]
inner = extract_inner_call!(stmt, length(new_code)+1)
while inner !== nothing
push!(new_code, inner)
push!(new_codelocs, loc)
ssainc[i] += 1
inner = extract_inner_call!(stmt, length(new_code)+1)
end
push!(new_code, stmt)
push!(new_codelocs, loc)
end
# Fix all the SSAValues and GotoNodes
ssalookup = cumsum(ssainc)
renumber_ssa!(new_code, ssalookup)
code.ssavaluetypes = length(new_code)
return code
end

Expand Down
9 changes: 9 additions & 0 deletions test/interpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,12 @@ fkw(x::Int8; y=0, z="hello") = y
@test @interpret(Vararg.body.body.name) === Vararg.body.body.name
frame = JuliaInterpreter.prepare_toplevel(Main, :(Vararg.body.body.name))
@test JuliaInterpreter.finish_and_return!(JuliaStackFrame[], frame, true) === Vararg.body.body.name

ex = quote
if sizeof(JLOptions) === ccall(:jl_sizeof_jl_options, Int, ())
else
ccall(:jl_throw, Cvoid, (Any,), "Option structure mismatch")
end
end
frame = JuliaInterpreter.prepare_toplevel(Base, ex)
JuliaInterpreter.finish_and_return!(JuliaStackFrame[], frame, true)

0 comments on commit a54761a

Please sign in to comment.