First reported from core.matrix, but here's a smaller repro:
Cause: The jvm verifier doesn't like situations where we have an array on the stack typed as such, and on a later codepath it is used as target for an invokeinterface even if that path is unreachable because of a previous instance check.
Here's an explanation of exactly our case in pseudo bytecode:
Proposed: Insert an explicit checkcast to the interface on the target.
Also see: CLJ-1381
Patch: 0001-CLJ-1790-emit-a-cast-to-the-interface-during-procol-.patch
Do we know why core.matrix works with Clojure 1.6/1.7 then?
It doesn't.
I attached a patch that fixes this issue.
It's caused by the jvm verifier understanding that the object on the stack is an array and thus can never be an instance of the protcol interface, but not being able to understant that the code path leading to the direct protocol interface method invocation can never be reached because of a branch guided by an instance check for that interface on the target
Apologies, it is possible I just hadn't tested this code path thoroughly before.
It only seems to get triggered in certain circumstances, the following behaviour is interesting:
Perhaps it only happens when the callsite has type information about the protocol parameter?
Correct, apparently the jvm verifier doesn't like situations where we have an array on the stack typed as such, and on a later codepath it is used as target for an invokeinterface even if that path is unreachable because of a previous instance check.
here's an explaination of exactly our case in pseudo bytecode:
Thanks for the tight repro!
I am marking this screened because the explanation makes sense and the patch works as advertised, but will caveat that I don't have a deep understanding here.