Skip to content

Commit

Permalink
add ability to evaluate ssavalues and locals (#395)
Browse files Browse the repository at this point in the history
* add ability to evaluate ssavalues and locals

* fix for 1.0

* add some docs
  • Loading branch information
KristofferC authored May 23, 2020
1 parent 4d7becb commit 423b4e6
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,9 @@ julia> JuliaInterpreter.locals(frame)
#self# = capture
x = Core.Box(2)
```
"Special" values like SSA values and slots (shown in lowered code as e.g. `%3` and `@_4`
respectively) can be evaluated using the syntax `var"%3"` and `var"@_4"` respectively.
"""
function eval_code end

Expand All @@ -508,9 +511,13 @@ function eval_code(frame::Frame, expr)
end
# see https://github.com/JuliaLang/julia/issues/31255 for the Symbol("") check
vars = filter(v -> v.name != Symbol(""), locals(frame))
defined_ssa = findall(x -> x!=0, [isassigned(data.ssavalues, i) for i in 1:length(data.ssavalues)])
defined_locals = findall(x -> x isa Some, data.locals)
res = gensym()
eval_expr = Expr(:let,
Expr(:block, map(x->Expr(:(=), x...), [(v.name, maybe_quote(v.value isa Core.Box ? v.value.contents : v.value)) for v in vars])...),
Expr(:block, map(x->Expr(:(=), x...), [(v.name, maybe_quote(v.value isa Core.Box ? v.value.contents : v.value)) for v in vars])...,
map(x->Expr(:(=), x...), [(Symbol("%$i"), data.ssavalues[i]) for i in defined_ssa])...,
map(x->Expr(:(=), x...), [(Symbol("@_$i"), data.locals[i].value) for i in defined_locals])...),
Expr(:block,
Expr(:(=), res, expr),
Expr(:tuple, res, Expr(:tuple, [v.name for v in vars]...))
Expand Down
11 changes: 11 additions & 0 deletions test/eval_code.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,14 @@ fr, bp = debug_command(fr, :c)
@test eval_code(fr, "garbage") == ones(10)
eval_code(fr, "non_accessible_variable = 5.0")
@test eval_code(fr, "non_accessible_variable") == 5.0

if VERSION >= v"1.4" # for var"" syntax
# Evaluating SSAValues
f(x) = x^2
frame = JuliaInterpreter.enter_call(f, 5)
JuliaInterpreter.step_expr!(frame)
JuliaInterpreter.step_expr!(frame)
# This could change with changes to Julia lowering
@test eval_code(frame, "var\"%2\"") == Val(2)
@test eval_code(frame, "var\"@_1\"") == f
end

0 comments on commit 423b4e6

Please sign in to comment.