diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 6324456fa1..49c2daa161 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -1651,7 +1651,7 @@ private static Class toInvokerParamType(Class c) { * If targetClass is FI and has an adaptable functional method * Find fn invoker method matching adaptable method of FI * Emit bytecode for (expr is emitted): - * if(expr instanceof IFn) + * if(expr instanceof IFn && !(expr instanceof FI)) * invokeDynamic(targetMethod, fnInvokerImplMethod) * Else emit nothing */ @@ -1686,15 +1686,18 @@ static boolean maybeEmitFIAdapter(ObjExpr objx, GeneratorAdapter gen, Expr expr, try { java.lang.reflect.Method fnInvokerMethod = FnInvokers.class.getMethod(invokerMethodName, invokerParams); - // if(exp instanceof IFn) { emitInvokeDynamic(targetMethod, fnInvokerMethod) } + // if not (expr instanceof IFn), go to end label expr.emit(C.EXPRESSION, objx, gen); gen.dup(); gen.instanceOf(ifnType); - - // if not instanceof IFn, go to end Label endLabel = gen.newLabel(); gen.ifZCmp(Opcodes.IFEQ, endLabel); + // if (expr instanceof FI), go to end label + gen.dup(); + gen.instanceOf(samType); + gen.ifZCmp(Opcodes.IFNE, endLabel); + // else adapt fn invoker method as impl for target method emitInvokeDynamicAdapter(gen, targetClass, targetMethod, FnInvokers.class, fnInvokerMethod); diff --git a/test/clojure/test_clojure/java_interop.clj b/test/clojure/test_clojure/java_interop.clj index 4a50388417..4b1112c9b5 100644 --- a/test/clojure/test_clojure/java_interop.clj +++ b/test/clojure/test_clojure/java_interop.clj @@ -859,3 +859,15 @@ (testing "Static method accepting FI arg, provided overloaded static class FI" (is (= \S (FunctionalTester/staticMethodWithFIArg "Static" 0 FunctionalTester/getChar))))) + +(deftest CLJ-2898-reified-objs-both-IFn-and-FI + (let [tl (ThreadLocal/withInitial + (reify + java.util.function.Supplier + (get [_] 100) + + clojure.lang.IFn + (applyTo [_ _] 201) + (invoke [_] 200)))] + ;; should not be adapted and use Supplier.get() impl on tl + (is (= 100 (.get tl))))) \ No newline at end of file
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: