From e98fc126c4118bcf8750ea85bb25bca2d85b145f Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Sat, 27 Jun 2020 20:15:14 +0700 Subject: [PATCH] Merge various codegen utilities into one file --- .../kmath/asm/internal/buildName.kt | 22 ------- .../kmath/asm/internal/classWriters.kt | 17 ----- .../scientifik/kmath/asm/internal/classes.kt | 7 -- .../{specialization.kt => codegenUtils.kt} | 64 ++++++++++++++++++- .../kmath/asm/internal/instructionAdapters.kt | 10 --- .../kmath/asm/internal/methodVisitors.kt | 9 --- 6 files changed, 63 insertions(+), 66 deletions(-) delete mode 100644 kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/buildName.kt delete mode 100644 kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/classWriters.kt delete mode 100644 kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/classes.kt rename kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/{specialization.kt => codegenUtils.kt} (57%) delete mode 100644 kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/instructionAdapters.kt delete mode 100644 kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/methodVisitors.kt diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/buildName.kt b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/buildName.kt deleted file mode 100644 index 41dbf5807..000000000 --- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/buildName.kt +++ /dev/null @@ -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) -} diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/classWriters.kt b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/classWriters.kt deleted file mode 100644 index 7f0770b28..000000000 --- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/classWriters.kt +++ /dev/null @@ -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) diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/classes.kt b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/classes.kt deleted file mode 100644 index dc0b35531..000000000 --- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/classes.kt +++ /dev/null @@ -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) diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/specialization.kt b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/codegenUtils.kt similarity index 57% rename from kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/specialization.kt rename to kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/codegenUtils.kt index 003dc47dd..46d07976d 100644 --- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/specialization.kt +++ b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/codegenUtils.kt @@ -1,8 +1,12 @@ package scientifik.kmath.asm.internal +import org.objectweb.asm.* 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 kotlin.reflect.KClass private val methodNameAdapters: Map, String> by lazy { hashMapOf( @@ -15,6 +19,60 @@ private val methodNameAdapters: Map, 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 * type expectation stack for needed arity. @@ -60,6 +118,9 @@ private fun AsmBuilder.tryInvokeSpecific(context: Algebra, name: Strin return true } +/** + * Builds specialized algebra call with option to fallback to generic algebra operation accepting String. + */ internal fun AsmBuilder.buildAlgebraOperationCall( context: Algebra, name: String, @@ -84,3 +145,4 @@ internal fun AsmBuilder.buildAlgebraOperationCall( expectedArity = arity ) } + diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/instructionAdapters.kt b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/instructionAdapters.kt deleted file mode 100644 index f47293687..000000000 --- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/instructionAdapters.kt +++ /dev/null @@ -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 -} diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/methodVisitors.kt b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/methodVisitors.kt deleted file mode 100644 index aaae02ebb..000000000 --- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/methodVisitors.kt +++ /dev/null @@ -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)