ASM Bytecode Generation to unwrap Expressions of adv-expr API #94
@ -18,9 +18,10 @@ internal fun buildName(expression: AsmExpression<*>, collision: Int = 0): String
|
||||
return buildName(expression, collision + 1)
|
||||
}
|
||||
|
||||
inline fun <reified T> AsmExpression<T>.compile(algebra: Algebra<T>): Expression<T> {
|
||||
@PublishedApi
|
||||
internal inline fun <reified T> AsmExpression<T>.compile(algebra: Algebra<T>): Expression<T> {
|
||||
val ctx = AsmGenerationContext(T::class.java, algebra, buildName(this))
|
||||
invoke(ctx)
|
||||
compile(ctx)
|
||||
return ctx.generate()
|
||||
}
|
||||
|
@ -1,14 +1,31 @@
|
||||
|
||||
package scientifik.kmath.asm
|
||||
|
||||
import scientifik.kmath.asm.internal.hasSpecific
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
import scientifik.kmath.asm.internal.optimize
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
import scientifik.kmath.asm.internal.tryInvokeSpecific
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
import scientifik.kmath.expressions.Expression
|
||||
import scientifik.kmath.expressions.ExpressionAlgebra
|
||||
import scientifik.kmath.operations.*
|
||||
import kotlin.reflect.full.memberFunctions
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
import kotlin.reflect.jvm.jvmName
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
|
||||
/**
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
* A function declaration that could be compiled to [AsmGenerationContext].
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
*
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
* @param T the type the stored function returns.
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
*/
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
interface AsmExpression<T> {
|
||||
/**
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
* Tries to evaluate this function without its variables. This method is intended for optimization.
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
*
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
* @return `null` if the function depends on its variables, the value if the function is a constant.
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
*/
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
fun tryEvaluate(): T? = null
|
||||
fun invoke(gen: AsmGenerationContext<T>)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
/**
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
* Compiles this declaration.
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
*
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
* @param gen the target [AsmGenerationContext].
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
*/
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
fun compile(gen: AsmGenerationContext<T>)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
}
|
||||
|
||||
internal class AsmUnaryOperation<T>(private val context: Algebra<T>, private val name: String, expr: AsmExpression<T>) :
|
||||
@ -16,13 +33,13 @@ internal class AsmUnaryOperation<T>(private val context: Algebra<T>, private val
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
OK OK
OK OK
It seems like It seems like `compile` is a better name.
It seems like It seems like `compile` is a better name.
|
||||
private val expr: AsmExpression<T> = expr.optimize()
|
||||
override fun tryEvaluate(): T? = context { unaryOperation(name, expr.tryEvaluate() ?: return@context null) }
|
||||
|
||||
override fun invoke(gen: AsmGenerationContext<T>) {
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
override fun compile(gen: AsmGenerationContext<T>) {
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
gen.visitLoadAlgebra()
|
||||
|
||||
if (!hasSpecific(context, name, 1))
|
||||
gen.visitStringConstant(name)
|
||||
|
||||
expr.invoke(gen)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
expr.compile(gen)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
|
||||
if (gen.tryInvokeSpecific(context, name, 1))
|
||||
return
|
||||
@ -54,14 +71,14 @@ internal class AsmBinaryOperation<T>(
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
OK OK
OK OK
It seems like It seems like `compile` is a better name.
It seems like It seems like `compile` is a better name.
|
||||
)
|
||||
}
|
||||
|
||||
override fun invoke(gen: AsmGenerationContext<T>) {
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
override fun compile(gen: AsmGenerationContext<T>) {
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
gen.visitLoadAlgebra()
|
||||
|
||||
if (!hasSpecific(context, name, 2))
|
||||
gen.visitStringConstant(name)
|
||||
|
||||
first.invoke(gen)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
second.invoke(gen)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
first.compile(gen)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
second.compile(gen)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
|
||||
if (gen.tryInvokeSpecific(context, name, 2))
|
||||
return
|
||||
@ -79,13 +96,13 @@ internal class AsmBinaryOperation<T>(
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
OK OK
OK OK
It seems like It seems like `compile` is a better name.
It seems like It seems like `compile` is a better name.
|
||||
|
||||
internal class AsmVariableExpression<T>(private val name: String, private val default: T? = null) :
|
||||
AsmExpression<T> {
|
||||
override fun invoke(gen: AsmGenerationContext<T>): Unit = gen.visitLoadFromVariables(name, default)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
override fun compile(gen: AsmGenerationContext<T>): Unit = gen.visitLoadFromVariables(name, default)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
}
|
||||
|
||||
internal class AsmConstantExpression<T>(private val value: T) :
|
||||
AsmExpression<T> {
|
||||
override fun tryEvaluate(): T = value
|
||||
override fun invoke(gen: AsmGenerationContext<T>): Unit = gen.visitLoadFromConstants(value)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
override fun compile(gen: AsmGenerationContext<T>): Unit = gen.visitLoadFromConstants(value)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
}
|
||||
|
||||
internal class AsmConstProductExpression<T>(
|
||||
@ -98,10 +115,10 @@ internal class AsmConstProductExpression<T>(
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
OK OK
OK OK
It seems like It seems like `compile` is a better name.
It seems like It seems like `compile` is a better name.
|
||||
|
||||
override fun tryEvaluate(): T? = context { (expr.tryEvaluate() ?: return@context null) * const }
|
||||
|
||||
override fun invoke(gen: AsmGenerationContext<T>) {
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
override fun compile(gen: AsmGenerationContext<T>) {
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
gen.visitLoadAlgebra()
|
||||
gen.visitNumberConstant(const)
|
||||
expr.invoke(gen)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
expr.compile(gen)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
|
||||
gen.visitAlgebraOperation(
|
||||
owner = AsmGenerationContext.SPACE_OPERATIONS_CLASS,
|
||||
@ -117,7 +134,7 @@ internal class AsmNumberExpression<T>(private val context: NumericAlgebra<T>, pr
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
OK OK
OK OK
It seems like It seems like `compile` is a better name.
It seems like It seems like `compile` is a better name.
|
||||
AsmExpression<T> {
|
||||
override fun tryEvaluate(): T? = context.number(value)
|
||||
|
||||
override fun invoke(gen: AsmGenerationContext<T>): Unit = gen.visitNumberConstant(value)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
override fun compile(gen: AsmGenerationContext<T>): Unit = gen.visitNumberConstant(value)
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
It seems like It seems like `compile` is a better name.
|
||||
}
|
||||
|
||||
internal abstract class FunctionalCompiledExpression<T> internal constructor(
|
||||
|
||||
Add documentation since the interface is public. Add documentation since the interface is public.
Add documentation since the interface is public. Add documentation since the interface is public.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
does it make sense to do invoke without does it make sense to do invoke without `operator`? It seems that it should be renamed to `compile`. Those method need to be documented as well.
OK OK
OK OK
OK OK
OK OK
It seems like It seems like `compile` is a better name.
It seems like It seems like `compile` is a better name.
|
@ -5,6 +5,9 @@ import org.objectweb.asm.Label
|
||||
Could the constructor be made internal? Could the constructor be made internal?
Could the constructor be made internal? Could the constructor be made internal?
I'll check I'll check
I'll check I'll check
It can. It can.
It can. It can.
|
||||
import org.objectweb.asm.MethodVisitor
|
||||
import org.objectweb.asm.Opcodes
|
||||
import scientifik.kmath.asm.AsmGenerationContext.ClassLoader
|
||||
import scientifik.kmath.asm.internal.visitLdcOrDConstInsn
|
||||
Could the constructor be made internal? Could the constructor be made internal?
I'll check I'll check
It can. It can.
|
||||
import scientifik.kmath.asm.internal.visitLdcOrFConstInsn
|
||||
Could the constructor be made internal? Could the constructor be made internal?
I'll check I'll check
It can. It can.
|
||||
import scientifik.kmath.asm.internal.visitLdcOrIConstInsn
|
||||
Could the constructor be made internal? Could the constructor be made internal?
I'll check I'll check
It can. It can.
|
||||
import scientifik.kmath.operations.Algebra
|
||||
|
||||
/**
|
||||
@ -16,7 +19,7 @@ import scientifik.kmath.operations.Algebra
|
||||
Could the constructor be made internal? Could the constructor be made internal?
Could the constructor be made internal? Could the constructor be made internal?
I'll check I'll check
I'll check I'll check
It can. It can.
It can. It can.
|
||||
* @param algebra the algebra the applied AsmExpressions use.
|
||||
* @param className the unique class name of new loaded class.
|
||||
*/
|
||||
class AsmGenerationContext<T>(
|
||||
Could the constructor be made internal? Could the constructor be made internal?
I'll check I'll check
It can. It can.
|
||||
class AsmGenerationContext<T> @PublishedApi internal constructor(
|
||||
Could the constructor be made internal? Could the constructor be made internal?
I'll check I'll check
It can. It can.
|
||||
private val classOfT: Class<*>,
|
||||
private val algebra: Algebra<T>,
|
||||
private val className: String
|
||||
|
||||
Could the constructor be made internal? Could the constructor be made internal?
Could the constructor be made internal? Could the constructor be made internal?
I'll check I'll check
I'll check I'll check
It can. It can.
It can. It can.
|
@ -1,4 +1,4 @@
|
||||
package scientifik.kmath.asm
|
||||
package scientifik.kmath.asm.internal
|
||||
|
||||
import org.objectweb.asm.MethodVisitor
|
||||
import org.objectweb.asm.Opcodes.*
|
@ -1,8 +1,10 @@
|
||||
package scientifik.kmath.asm
|
||||
package scientifik.kmath.asm.internal
|
||||
|
||||
import org.objectweb.asm.Opcodes
|
||||
import scientifik.kmath.asm.AsmConstantExpression
|
||||
import scientifik.kmath.asm.AsmExpression
|
||||
import scientifik.kmath.asm.AsmGenerationContext
|
||||
import scientifik.kmath.operations.Algebra
|
||||
import scientifik.kmath.operations.ByteRing
|
||||
|
||||
private val methodNameAdapters: Map<String, String> = mapOf("+" to "add", "*" to "multiply", "/" to "divide")
|
||||
|
Add documentation since the interface is public.
Add documentation since the interface is public.
does it make sense to do invoke without
operator
? It seems that it should be renamed tocompile
. Those method need to be documented as well.does it make sense to do invoke without
operator
? It seems that it should be renamed tocompile
. Those method need to be documented as well.OK
OK
OK
OK
It seems like
compile
is a better name.It seems like
compile
is a better name.