Dev #127
@ -57,13 +57,13 @@ internal class AsmBinaryOperation<T>(
|
||||
override fun invoke(gen: AsmGenerationContext<T>) {
|
||||
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(
|
||||
|
@ -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<T>(
|
||||
}
|
||||
|
||||
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<T>(
|
||||
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()
|
||||
}
|
||||
|
||||
|
@ -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<String, String> = mapOf("+" to "add", "*" to "multiply", "/" to "divide")
|
||||
|
||||
internal fun <T> hasSpecific(context: Algebra<T>, 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 <T> hasSpecific(context: Algebra<T>, name: String, arity: Int): Boo
|
||||
internal fun <T> AsmGenerationContext<T>.tryInvokeSpecific(context: Algebra<T>, 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 <T> AsmGenerationContext<T>.tryInvokeSpecific(context: Algebra<T>,
|
||||
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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user