Specify type explicitly, minor implementation refactor

This commit is contained in:
Iaroslav 2020-06-25 20:54:14 +07:00
parent c8fbc2d8be
commit e2cc3c8efe
No known key found for this signature in database
GPG Key ID: 46E15E4A31B3BCD7
3 changed files with 21 additions and 27 deletions

View File

@ -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
) )
} }
} }

View File

@ -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()
} }

View File

@ -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
) )