Dev #127
@ -57,13 +57,13 @@ internal class AsmBinaryOperation<T>(
|
|||||||
override fun invoke(gen: AsmGenerationContext<T>) {
|
override fun invoke(gen: AsmGenerationContext<T>) {
|
||||||
gen.visitLoadAlgebra()
|
gen.visitLoadAlgebra()
|
||||||
|
|
||||||
if (!hasSpecific(context, name, 1))
|
if (!hasSpecific(context, name, 2))
|
||||||
gen.visitStringConstant(name)
|
gen.visitStringConstant(name)
|
||||||
|
|
||||||
first.invoke(gen)
|
first.invoke(gen)
|
||||||
second.invoke(gen)
|
second.invoke(gen)
|
||||||
|
|
||||||
if (gen.tryInvokeSpecific(context, name, 1))
|
if (gen.tryInvokeSpecific(context, name, 2))
|
||||||
return
|
return
|
||||||
|
|
||||||
gen.visitAlgebraOperation(
|
gen.visitAlgebraOperation(
|
||||||
|
@ -4,6 +4,7 @@ import org.objectweb.asm.ClassWriter
|
|||||||
import org.objectweb.asm.Label
|
import org.objectweb.asm.Label
|
||||||
import org.objectweb.asm.MethodVisitor
|
import org.objectweb.asm.MethodVisitor
|
||||||
import org.objectweb.asm.Opcodes
|
import org.objectweb.asm.Opcodes
|
||||||
|
import scientifik.kmath.asm.AsmGenerationContext.ClassLoader
|
||||||
import scientifik.kmath.operations.Algebra
|
import scientifik.kmath.operations.Algebra
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -245,8 +246,10 @@ class AsmGenerationContext<T>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
visitLdcInsn(name)
|
visitLdcInsn(name)
|
||||||
visitMethodInsn(Opcodes.INVOKEINTERFACE,
|
visitMethodInsn(
|
||||||
MAP_CLASS, "get", "(L$OBJECT_CLASS;)L$OBJECT_CLASS;", true)
|
Opcodes.INVOKEINTERFACE,
|
||||||
|
MAP_CLASS, "get", "(L$OBJECT_CLASS;)L$OBJECT_CLASS;", true
|
||||||
|
)
|
||||||
visitCastToT()
|
visitCastToT()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,9 +265,15 @@ class AsmGenerationContext<T>(
|
|||||||
invokeMethodVisitor.visitTypeInsn(Opcodes.CHECKCAST, T_ALGEBRA_CLASS)
|
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++
|
maxStack++
|
||||||
invokeMethodVisitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, owner, method, descriptor, true)
|
invokeMethodVisitor.visitMethodInsn(opcode, owner, method, descriptor, isInterface)
|
||||||
visitCastToT()
|
visitCastToT()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
package scientifik.kmath.asm
|
package scientifik.kmath.asm
|
||||||
|
|
||||||
|
import org.objectweb.asm.Opcodes
|
||||||
import scientifik.kmath.operations.Algebra
|
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")
|
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 {
|
internal fun <T> hasSpecific(context: Algebra<T>, name: String, arity: Int): Boolean {
|
||||||
val aName = methodNameAdapters[name] ?: name
|
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 false
|
||||||
|
|
||||||
return true
|
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 {
|
internal fun <T> AsmGenerationContext<T>.tryInvokeSpecific(context: Algebra<T>, name: String, arity: Int): Boolean {
|
||||||
val aName = methodNameAdapters[name] ?: name
|
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 false
|
||||||
|
|
||||||
val owner = context::class.jvmName.replace('.', '/')
|
val owner = context::class.java.name.replace('.', '/')
|
||||||
|
|
||||||
val sig = buildString {
|
val sig = buildString {
|
||||||
append('(')
|
append('(')
|
||||||
@ -30,7 +29,13 @@ internal fun <T> AsmGenerationContext<T>.tryInvokeSpecific(context: Algebra<T>,
|
|||||||
append("L${AsmGenerationContext.OBJECT_CLASS};")
|
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
|
return true
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user