forked from kscience/kmath
Merge various codegen utilities into one file
This commit is contained in:
parent
efcfb44253
commit
e98fc126c4
@ -1,22 +0,0 @@
|
|||||||
package scientifik.kmath.asm.internal
|
|
||||||
|
|
||||||
import scientifik.kmath.ast.MST
|
|
||||||
import scientifik.kmath.expressions.Expression
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a class name for [Expression] subclassed to implement [mst] provided.
|
|
||||||
*
|
|
||||||
* This methods helps to avoid collisions of class name to prevent loading several classes with the same name. If there
|
|
||||||
* is a colliding class, change [collision] parameter or leave it `0` to check existing classes recursively.
|
|
||||||
*/
|
|
||||||
internal tailrec fun buildName(mst: MST, collision: Int = 0): String {
|
|
||||||
val name = "scientifik.kmath.asm.generated.AsmCompiledExpression_${mst.hashCode()}_$collision"
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class.forName(name)
|
|
||||||
} catch (ignored: ClassNotFoundException) {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
return buildName(mst, collision + 1)
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
package scientifik.kmath.asm.internal
|
|
||||||
|
|
||||||
import org.objectweb.asm.ClassWriter
|
|
||||||
import org.objectweb.asm.FieldVisitor
|
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
internal inline fun ClassWriter(flags: Int, block: ClassWriter.() -> Unit): ClassWriter =
|
|
||||||
ClassWriter(flags).apply(block)
|
|
||||||
|
|
||||||
internal inline fun ClassWriter.visitField(
|
|
||||||
access: Int,
|
|
||||||
name: String,
|
|
||||||
descriptor: String,
|
|
||||||
signature: String?,
|
|
||||||
value: Any?,
|
|
||||||
block: FieldVisitor.() -> Unit
|
|
||||||
): FieldVisitor = visitField(access, name, descriptor, signature, value).apply(block)
|
|
@ -1,7 +0,0 @@
|
|||||||
package scientifik.kmath.asm.internal
|
|
||||||
|
|
||||||
import org.objectweb.asm.Type
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
internal val KClass<*>.asm: Type
|
|
||||||
get() = Type.getType(java)
|
|
@ -1,8 +1,12 @@
|
|||||||
package scientifik.kmath.asm.internal
|
package scientifik.kmath.asm.internal
|
||||||
|
|
||||||
|
import org.objectweb.asm.*
|
||||||
import org.objectweb.asm.Opcodes.INVOKEVIRTUAL
|
import org.objectweb.asm.Opcodes.INVOKEVIRTUAL
|
||||||
import org.objectweb.asm.Type
|
import org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
import scientifik.kmath.ast.MST
|
||||||
|
import scientifik.kmath.expressions.Expression
|
||||||
import scientifik.kmath.operations.Algebra
|
import scientifik.kmath.operations.Algebra
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
private val methodNameAdapters: Map<Pair<String, Int>, String> by lazy {
|
private val methodNameAdapters: Map<Pair<String, Int>, String> by lazy {
|
||||||
hashMapOf(
|
hashMapOf(
|
||||||
@ -15,6 +19,60 @@ private val methodNameAdapters: Map<Pair<String, Int>, String> by lazy {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val KClass<*>.asm: Type
|
||||||
|
get() = Type.getType(java)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an [InstructionAdapter] from this [MethodVisitor].
|
||||||
|
*/
|
||||||
|
private fun MethodVisitor.instructionAdapter(): InstructionAdapter = InstructionAdapter(this)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an [InstructionAdapter] from this [MethodVisitor] and applies [block] to it.
|
||||||
|
*/
|
||||||
|
internal fun MethodVisitor.instructionAdapter(block: InstructionAdapter.() -> Unit): InstructionAdapter =
|
||||||
|
instructionAdapter().apply(block)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a [Label], then applies it to this visitor.
|
||||||
|
*/
|
||||||
|
internal fun MethodVisitor.label(): Label {
|
||||||
|
val l = Label()
|
||||||
|
visitLabel(l)
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a class name for [Expression] subclassed to implement [mst] provided.
|
||||||
|
*
|
||||||
|
* This methods helps to avoid collisions of class name to prevent loading several classes with the same name. If there
|
||||||
|
* is a colliding class, change [collision] parameter or leave it `0` to check existing classes recursively.
|
||||||
|
*/
|
||||||
|
internal tailrec fun buildName(mst: MST, collision: Int = 0): String {
|
||||||
|
val name = "scientifik.kmath.asm.generated.AsmCompiledExpression_${mst.hashCode()}_$collision"
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class.forName(name)
|
||||||
|
} catch (ignored: ClassNotFoundException) {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildName(mst, collision + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
internal inline fun ClassWriter(flags: Int, block: ClassWriter.() -> Unit): ClassWriter =
|
||||||
|
ClassWriter(flags).apply(block)
|
||||||
|
|
||||||
|
internal inline fun ClassWriter.visitField(
|
||||||
|
access: Int,
|
||||||
|
name: String,
|
||||||
|
descriptor: String,
|
||||||
|
signature: String?,
|
||||||
|
value: Any?,
|
||||||
|
block: FieldVisitor.() -> Unit
|
||||||
|
): FieldVisitor = visitField(access, name, descriptor, signature, value).apply(block)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the target [context] for code generation contains a method with needed [name] and [arity], also builds
|
* Checks if the target [context] for code generation contains a method with needed [name] and [arity], also builds
|
||||||
* type expectation stack for needed arity.
|
* type expectation stack for needed arity.
|
||||||
@ -60,6 +118,9 @@ private fun <T> AsmBuilder<T>.tryInvokeSpecific(context: Algebra<T>, name: Strin
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds specialized algebra call with option to fallback to generic algebra operation accepting String.
|
||||||
|
*/
|
||||||
internal fun <T> AsmBuilder<T>.buildAlgebraOperationCall(
|
internal fun <T> AsmBuilder<T>.buildAlgebraOperationCall(
|
||||||
context: Algebra<T>,
|
context: Algebra<T>,
|
||||||
name: String,
|
name: String,
|
||||||
@ -84,3 +145,4 @@ internal fun <T> AsmBuilder<T>.buildAlgebraOperationCall(
|
|||||||
expectedArity = arity
|
expectedArity = arity
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +0,0 @@
|
|||||||
package scientifik.kmath.asm.internal
|
|
||||||
|
|
||||||
import org.objectweb.asm.Label
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter
|
|
||||||
|
|
||||||
internal fun InstructionAdapter.label(): Label {
|
|
||||||
val l = Label()
|
|
||||||
visitLabel(l)
|
|
||||||
return l
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
package scientifik.kmath.asm.internal
|
|
||||||
|
|
||||||
import org.objectweb.asm.MethodVisitor
|
|
||||||
import org.objectweb.asm.commons.InstructionAdapter
|
|
||||||
|
|
||||||
internal fun MethodVisitor.instructionAdapter(): InstructionAdapter = InstructionAdapter(this)
|
|
||||||
|
|
||||||
internal fun MethodVisitor.instructionAdapter(block: InstructionAdapter.() -> Unit): InstructionAdapter =
|
|
||||||
instructionAdapter().apply(block)
|
|
Loading…
Reference in New Issue
Block a user