Using `@overlay` like Cassette.jl?

I was wondering if anybody knew if it is possible to use Base.Experimental.@overlay in a way similar the overdubbing feature of Cassette.jl? In particular, I want to override the behavior of every single function compiled, rather than only a few explicitly-listed methods.

Sadly it seems like Cassette.jl is unmaintained these days so I’ve been hunting for an alternative. I found Base.Experimental.@overlay alongside this “MiniCassette” in the Compiler test suite: julia/Compiler/test/contextual.jl at 71bfbb3b0134c05e1af49c385738b8f5d8f06e7c · JuliaLang/julia · GitHub. However, I was unable to repurpose this working for general overdubbing. I tried the following:

julia> import .MiniCassette: overdub

julia> f(x) = sin(x)
f (generic function with 1 method)

julia> @eval function overdub(ctx::Ctx, f, args...)
           $(Expr(:meta, :generated_only))
           f in (sin, f) && println("Calling from ", f, " with args ", args)
           $(Expr(:meta, :generated, MiniCassette.overdub_generator))
       end
overdub (generic function with 3 methods)

Basically seeing if I can inject this print statement into sin and f via a conditional. However, it seems MiniCassette is not set up for that, as it gave me this error:

julia> overdub(Ctx(), f, 1.0)
ERROR: AssertionError: !(mi.def.isva)
Stacktrace:

Whereas my desired output would be:

Calling from sin with args (1.0,)
Calling from f with args (1.0,)

Does anybody have any advice for getting Cassette-like overdubbing on 1.12? Again, I want to overdub all functions (it’s for BorrowChecker.jl), so I cannot explicitly declare all methods in a method table.

Tagging some people I see with commits to that file… @aviatesk @Oscar_Smith @maleadt @jameson. Any tips for getting something like this this?

2 Likes

Aside, what is @overlay? It’s not in the docs.

It’s a way to get contextual dispatch and override dispatch rules for a specific scope. In a particular scope, the methods you define have higher priority than all existing ones.

@overlay is part of this and adds a method to a custom method table. It’s in Base.Experimental but I could never find proper documentation for it; I only learned how to use it from code searches: Code search results · GitHub

There are some docstrings available via help though:

I think the README of CassetteOverlay.jl is a useful example of how to use something like this. (Though I also wish it had more docs!)

1 Like