Dev #127
@ -44,7 +44,7 @@ fun <T : Any> MST.compileWith(type: KClass<T>, algebra: Algebra<T>): Expression<
|
|||||||
AsmBuilder.OBJECT_TYPE
|
AsmBuilder.OBJECT_TYPE
|
||||||
),
|
),
|
||||||
|
|
||||||
tArity = 1
|
expectedArity = 1
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is MST.Binary -> {
|
is MST.Binary -> {
|
||||||
@ -64,7 +64,7 @@ fun <T : Any> MST.compileWith(type: KClass<T>, algebra: Algebra<T>): Expression<
|
|||||||
AsmBuilder.OBJECT_TYPE
|
AsmBuilder.OBJECT_TYPE
|
||||||
),
|
),
|
||||||
|
|
||||||
tArity = 2
|
expectedArity = 2
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ internal class AsmBuilder<T> internal constructor(
|
|||||||
/**
|
/**
|
||||||
* State if [T] a primitive type, so [AsmBuilder] may generate direct primitive calls.
|
* State if [T] a primitive type, so [AsmBuilder] may generate direct primitive calls.
|
||||||
*/
|
*/
|
||||||
internal var primitiveMode = false
|
internal var primitiveMode: Boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Primitive type to apple for specific primitive calls. Use [OBJECT_TYPE], if not in [primitiveMode].
|
* Primitive type to apple for specific primitive calls. Use [OBJECT_TYPE], if not in [primitiveMode].
|
||||||
@ -91,7 +91,7 @@ internal class AsmBuilder<T> internal constructor(
|
|||||||
/**
|
/**
|
||||||
* Stack of useful objects types on stack to verify types.
|
* Stack of useful objects types on stack to verify types.
|
||||||
*/
|
*/
|
||||||
private val typeStack = Stack<Type>()
|
private val typeStack: Stack<Type> = Stack()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stack of useful objects types on stack expected by algebra calls.
|
* Stack of useful objects types on stack expected by algebra calls.
|
||||||
@ -345,6 +345,7 @@ internal class AsmBuilder<T> internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadConstant(value, boxed)
|
loadConstant(value, boxed)
|
||||||
|
|
||||||
if (!mustBeBoxed) unbox()
|
if (!mustBeBoxed) unbox()
|
||||||
else invokeMethodVisitor.checkcast(tType)
|
else invokeMethodVisitor.checkcast(tType)
|
||||||
}
|
}
|
||||||
@ -407,11 +408,11 @@ internal class AsmBuilder<T> internal constructor(
|
|||||||
owner: String,
|
owner: String,
|
||||||
method: String,
|
method: String,
|
||||||
descriptor: String,
|
descriptor: String,
|
||||||
tArity: Int,
|
expectedArity: Int,
|
||||||
opcode: Int = Opcodes.INVOKEINTERFACE
|
opcode: Int = Opcodes.INVOKEINTERFACE
|
||||||
) {
|
) {
|
||||||
run loop@{
|
run loop@{
|
||||||
repeat(tArity) {
|
repeat(expectedArity) {
|
||||||
if (typeStack.empty()) return@loop
|
if (typeStack.empty()) return@loop
|
||||||
typeStack.pop()
|
typeStack.pop()
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,7 @@ import org.objectweb.asm.Type
|
|||||||
import scientifik.kmath.operations.Algebra
|
import scientifik.kmath.operations.Algebra
|
||||||
|
|
||||||
private val methodNameAdapters: Map<String, String> by lazy {
|
private val methodNameAdapters: Map<String, String> by lazy {
|
||||||
hashMapOf(
|
hashMapOf("+" to "add", "*" to "multiply", "/" to "divide")
|
||||||
"+" to "add",
|
|
||||||
"*" to "multiply",
|
|
||||||
"/" to "divide"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,12 +15,10 @@ private val methodNameAdapters: Map<String, String> by lazy {
|
|||||||
* @return `true` if contains, else `false`.
|
* @return `true` if contains, else `false`.
|
||||||
*/
|
*/
|
||||||
internal fun <T> AsmBuilder<T>.buildExpectationStack(context: Algebra<T>, name: String, arity: Int): Boolean {
|
internal fun <T> AsmBuilder<T>.buildExpectationStack(context: Algebra<T>, name: String, arity: Int): Boolean {
|
||||||
val aName = methodNameAdapters[name] ?: name
|
val theName = methodNameAdapters[name] ?: name
|
||||||
|
val hasSpecific = context.javaClass.methods.find { it.name == theName && it.parameters.size == arity } != null
|
||||||
val hasSpecific = context.javaClass.methods.find { it.name == aName && it.parameters.size == arity } != null
|
|
||||||
val t = if (primitiveMode && hasSpecific) primitiveMask else tType
|
val t = if (primitiveMode && hasSpecific) primitiveMask else tType
|
||||||
repeat(arity) { expectationStack.push(t) }
|
repeat(arity) { expectationStack.push(t) }
|
||||||
|
|
||||||
return hasSpecific
|
return hasSpecific
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,25 +29,24 @@ internal fun <T> AsmBuilder<T>.buildExpectationStack(context: Algebra<T>, name:
|
|||||||
* @return `true` if contains, else `false`.
|
* @return `true` if contains, else `false`.
|
||||||
*/
|
*/
|
||||||
internal fun <T> AsmBuilder<T>.tryInvokeSpecific(context: Algebra<T>, name: String, arity: Int): Boolean {
|
internal fun <T> AsmBuilder<T>.tryInvokeSpecific(context: Algebra<T>, name: String, arity: Int): Boolean {
|
||||||
val aName = methodNameAdapters[name] ?: name
|
val theName = methodNameAdapters[name] ?: name
|
||||||
|
|
||||||
val method =
|
context.javaClass.methods.find {
|
||||||
context.javaClass.methods.find {
|
var suitableSignature = it.name == theName && it.parameters.size == arity
|
||||||
var suitableSignature = it.name == aName && it.parameters.size == arity
|
|
||||||
|
|
||||||
if (primitiveMode && it.isBridge)
|
if (primitiveMode && it.isBridge)
|
||||||
suitableSignature = false
|
suitableSignature = false
|
||||||
|
|
||||||
suitableSignature
|
suitableSignature
|
||||||
} ?: return false
|
} ?: return false
|
||||||
|
|
||||||
val owner = context::class.java.name.replace('.', '/')
|
val owner = context::class.asm
|
||||||
|
|
||||||
invokeAlgebraOperation(
|
invokeAlgebraOperation(
|
||||||
owner = owner,
|
owner = owner.internalName,
|
||||||
method = aName,
|
method = theName,
|
||||||
descriptor = Type.getMethodDescriptor(primitiveMaskBoxed, *Array(arity) { primitiveMask }),
|
descriptor = Type.getMethodDescriptor(primitiveMaskBoxed, *Array(arity) { primitiveMask }),
|
||||||
tArity = arity,
|
expectedArity = arity,
|
||||||
opcode = Opcodes.INVOKEVIRTUAL
|
opcode = Opcodes.INVOKEVIRTUAL
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user