# Using JuliaInterpreter breakpoints for custom code execution

**URL:** https://discourse.julialang.org/t/using-juliainterpreter-breakpoints-for-custom-code-execution/85890
**Category:** General Usage
**Created:** [August 17, 2022, 7:49pm UTC](https://discourse.julialang.org/t/using-juliainterpreter-breakpoints-for-custom-code-execution/85890 "2022-08-17T19:49:33Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [August 17, 2022, 7:49pm UTC](https://discourse.julialang.org/t/using-juliainterpreter-breakpoints-for-custom-code-execution/85890/1 "2022-08-17T19:49:33Z")

</div>

Let’s say that I’d like to run `foo()`, which calls `bar`, but replace the `bar` calls with calls to `yummy()`. This is the standard use case for packages like Cassette and IRTools (are there others now?), but even after all these years, they still look like half-heartedly-maintained fringe packages filled with caveats (which is understandable given how complex the problem space is!) Meanwhile, JuliaInterpreter has

```julia
julia> bp = @breakpoint sum([1, 2]) any(x->x>4, a);

julia> frame, bpref = @interpret sum([1,2,5]) # should trigger breakpoint
(Frame for sum(a::AbstractArray; dims, kw...) in Base at reducedim.jl:889
c 1 889 1 ─ nothing
  2 889 │ %2 = ($(QuoteNode(NamedTuple)))()
  3 889 │ %3 = Base.pairs(%2)
⋮
a = [1, 2, 5], breakpoint(sum(a::AbstractArray; dims, kw...) in Base at reducedim.jl:889, line 889))

```

Would it be that unreasonable to use a breakpoint on `bar`, then hack into the `frame` to change the call stack and insert a call to `yummy`?

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [August 20, 2022, 10:24am UTC](https://discourse.julialang.org/t/using-juliainterpreter-breakpoints-for-custom-code-execution/85890/2 "2022-08-20T10:24:45Z")

</div>

The answer seems to be yes, with this code being the critical piece:

```julia
const JInterp = JuliaInterpreter

function return_and_continue_execution(fr::JInterp.Frame, return_value)
    # This assume the `fr` is the _calling_ frame, for whatever call was breaked on, and indeed,
    # this is the case for JInterp breakpoints.
    # This code is a slimmed down version of `JInterp.maybe_reset_frame!`
    @assert !JInterp.is_leaf(fr)

    # First, abort the call to the breakpointed function
    JInterp.recycle(fr.callee)
    fr.callee = nothing

    # Then assign the value and move on to the next instruction
    JInterp.maybe_assign!(fr, return_value)
    fr.pc += 1 # maybe_reset_frame! has more complicated logic, that I don't get, but git-blame
                  # suggests that it's for kwarg funs

    return JInterp.finish_and_return!(fr) # continue execution
end

julia> using JuliaInterpreter

julia> sump7(x) = only(sum(x)) + 7
sump7 (generic function with 1 method)

julia> bp = @breakpoint sum([10,10]);

julia> frame, _ = @interpret sump7([100,100]);

julia> return_and_continue_execution(frame, 500)
507

```
