diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/AsmExpressions.kt b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/AsmExpressions.kt index c4039da81..83f3b7754 100644 --- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/AsmExpressions.kt +++ b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/AsmExpressions.kt @@ -57,13 +57,13 @@ internal class AsmBinaryOperation( override fun invoke(gen: AsmGenerationContext) { gen.visitLoadAlgebra() - if (!hasSpecific(context, name, 1)) + if (!hasSpecific(context, name, 2)) gen.visitStringConstant(name) first.invoke(gen) second.invoke(gen) - if (gen.tryInvokeSpecific(context, name, 1)) + if (gen.tryInvokeSpecific(context, name, 2)) return gen.visitAlgebraOperation( diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/AsmGenerationContext.kt b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/AsmGenerationContext.kt index 69a2b6c85..c10e56ba8 100644 --- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/AsmGenerationContext.kt +++ b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/AsmGenerationContext.kt @@ -4,6 +4,7 @@ import org.objectweb.asm.ClassWriter import org.objectweb.asm.Label import org.objectweb.asm.MethodVisitor import org.objectweb.asm.Opcodes +import scientifik.kmath.asm.AsmGenerationContext.ClassLoader import scientifik.kmath.operations.Algebra /** @@ -245,8 +246,10 @@ class AsmGenerationContext( } visitLdcInsn(name) - visitMethodInsn(Opcodes.INVOKEINTERFACE, - MAP_CLASS, "get", "(L$OBJECT_CLASS;)L$OBJECT_CLASS;", true) + visitMethodInsn( + Opcodes.INVOKEINTERFACE, + MAP_CLASS, "get", "(L$OBJECT_CLASS;)L$OBJECT_CLASS;", true + ) visitCastToT() } @@ -262,9 +265,15 @@ class AsmGenerationContext( invokeMethodVisitor.visitTypeInsn(Opcodes.CHECKCAST, T_ALGEBRA_CLASS) } - internal fun visitAlgebraOperation(owner: String, method: String, descriptor: String) { + internal fun visitAlgebraOperation( + owner: String, + method: String, + descriptor: String, + opcode: Int = Opcodes.INVOKEINTERFACE, + isInterface: Boolean = true + ) { maxStack++ - invokeMethodVisitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, owner, method, descriptor, true) + invokeMethodVisitor.visitMethodInsn(opcode, owner, method, descriptor, isInterface) visitCastToT() } diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/Optimization.kt b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/Optimization.kt index 4e094fdd8..3198fa8ec 100644 --- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/Optimization.kt +++ b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/Optimization.kt @@ -1,15 +1,14 @@ package scientifik.kmath.asm +import org.objectweb.asm.Opcodes import scientifik.kmath.operations.Algebra -import kotlin.reflect.full.memberFunctions -import kotlin.reflect.jvm.jvmName private val methodNameAdapters: Map = mapOf("+" to "add", "*" to "multiply", "/" to "divide") internal fun hasSpecific(context: Algebra, name: String, arity: Int): Boolean { val aName = methodNameAdapters[name] ?: name - context::class.memberFunctions.find { it.name == aName && it.parameters.size == arity } + context::class.java.methods.find { it.name == aName && it.parameters.size == arity } ?: return false return true @@ -18,10 +17,10 @@ internal fun hasSpecific(context: Algebra, name: String, arity: Int): Boo internal fun AsmGenerationContext.tryInvokeSpecific(context: Algebra, name: String, arity: Int): Boolean { val aName = methodNameAdapters[name] ?: name - context::class.memberFunctions.find { it.name == aName && it.parameters.size == arity } + context::class.java.methods.find { it.name == aName && it.parameters.size == arity } ?: return false - val owner = context::class.jvmName.replace('.', '/') + val owner = context::class.java.name.replace('.', '/') val sig = buildString { append('(') @@ -30,7 +29,13 @@ internal fun AsmGenerationContext.tryInvokeSpecific(context: Algebra, append("L${AsmGenerationContext.OBJECT_CLASS};") } - visitAlgebraOperation(owner = owner, method = aName, descriptor = sig) + visitAlgebraOperation( + owner = owner, + method = aName, + descriptor = sig, + opcode = Opcodes.INVOKEVIRTUAL, + isInterface = false + ) return true }