JVM_IR: buffer method bytecode in FunctionCodegen
This commit is contained in:
+6
-2
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature
|
|||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.org.objectweb.asm.*
|
import org.jetbrains.org.objectweb.asm.*
|
||||||
|
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
open class ClassCodegen protected constructor(
|
open class ClassCodegen protected constructor(
|
||||||
@@ -352,8 +353,11 @@ open class ClassCodegen protected constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val signature = FunctionCodegen(method, this).generate().asmMethod
|
val node = FunctionCodegen(method, this).generate()
|
||||||
jvmSignatureClashDetector.trackMethod(method, RawSignature(signature.name, signature.descriptor, MemberKind.METHOD))
|
node.accept(with(node) { visitor.newMethod(method.OtherOrigin, access, name, desc, signature, exceptions.toTypedArray()) })
|
||||||
|
jvmSignatureClashDetector.trackMethod(method, RawSignature(node.name, node.desc, MemberKind.METHOD))
|
||||||
|
|
||||||
|
val signature = Method(node.name, node.desc)
|
||||||
when (val metadata = method.metadata) {
|
when (val metadata = method.metadata) {
|
||||||
is MetadataSource.Property -> {
|
is MetadataSource.Property -> {
|
||||||
// We can't check for JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS because for interface methods
|
// We can't check for JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS because for interface methods
|
||||||
|
|||||||
+15
-16
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
|||||||
import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal
|
import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper
|
import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.wrapWithMaxLocalCalc
|
||||||
import org.jetbrains.kotlin.codegen.mangleNameIfNeeded
|
import org.jetbrains.kotlin.codegen.mangleNameIfNeeded
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.codegen.visitAnnotableParameterCount
|
import org.jetbrains.kotlin.codegen.visitAnnotableParameterCount
|
||||||
@@ -28,31 +29,39 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SYNTHETIC_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SYNTHETIC_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.STRICTFP_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.resolve.jvm.annotations.STRICTFP_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.SYNCHRONIZED_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.resolve.jvm.annotations.SYNCHRONIZED_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.org.objectweb.asm.*
|
import org.jetbrains.org.objectweb.asm.*
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||||
|
|
||||||
open class FunctionCodegen(
|
class FunctionCodegen(
|
||||||
private val irFunction: IrFunction,
|
private val irFunction: IrFunction,
|
||||||
private val classCodegen: ClassCodegen,
|
private val classCodegen: ClassCodegen,
|
||||||
private val inlinedInto: ExpressionCodegen? = null
|
private val inlinedInto: ExpressionCodegen? = null
|
||||||
) {
|
) {
|
||||||
private val context = classCodegen.context
|
private val context = classCodegen.context
|
||||||
|
|
||||||
fun generate(smapOverride: DefaultSourceMapper? = null): JvmMethodGenericSignature =
|
fun generate(smapOverride: DefaultSourceMapper? = null): MethodNode =
|
||||||
try {
|
try {
|
||||||
doGenerate(smapOverride)
|
doGenerate(smapOverride)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
throw RuntimeException("Exception while generating code for:\n${irFunction.dump()}", e)
|
throw RuntimeException("Exception while generating code for:\n${irFunction.dump()}", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doGenerate(smapOverride: DefaultSourceMapper?): JvmMethodGenericSignature {
|
private fun doGenerate(smapOverride: DefaultSourceMapper?): MethodNode {
|
||||||
val signature = context.methodSignatureMapper.mapSignatureWithGeneric(irFunction)
|
val signature = context.methodSignatureMapper.mapSignatureWithGeneric(irFunction)
|
||||||
val flags = irFunction.calculateMethodFlags()
|
val flags = irFunction.calculateMethodFlags()
|
||||||
var methodVisitor = createMethod(flags, signature)
|
val methodNode = MethodNode(
|
||||||
|
Opcodes.API_VERSION,
|
||||||
|
flags,
|
||||||
|
signature.asmMethod.name,
|
||||||
|
signature.asmMethod.descriptor,
|
||||||
|
signature.genericsSignature.takeIf { flags.and(Opcodes.ACC_SYNTHETIC) == 0 },
|
||||||
|
getThrownExceptions(irFunction)?.toTypedArray()
|
||||||
|
)
|
||||||
|
var methodVisitor: MethodVisitor = wrapWithMaxLocalCalc(methodNode)
|
||||||
|
|
||||||
if (context.state.generateParametersMetadata && flags.and(Opcodes.ACC_SYNTHETIC) == 0) {
|
if (context.state.generateParametersMetadata && flags.and(Opcodes.ACC_SYNTHETIC) == 0) {
|
||||||
generateParameterNames(irFunction, methodVisitor, signature, context.state)
|
generateParameterNames(irFunction, methodVisitor, signature, context.state)
|
||||||
@@ -103,7 +112,7 @@ open class FunctionCodegen(
|
|||||||
if (continuationClassCodegen.isInitialized() || irFunction.alwaysNeedsContinuation()) {
|
if (continuationClassCodegen.isInitialized() || irFunction.alwaysNeedsContinuation()) {
|
||||||
continuationClassCodegen.value.done()
|
continuationClassCodegen.value.done()
|
||||||
}
|
}
|
||||||
return signature
|
return methodNode
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since the only arguments to anonymous object constructors are captured variables and complex
|
// Since the only arguments to anonymous object constructors are captured variables and complex
|
||||||
@@ -156,16 +165,6 @@ open class FunctionCodegen(
|
|||||||
(if (isSynchronized) Opcodes.ACC_SYNCHRONIZED else 0)
|
(if (isSynchronized) Opcodes.ACC_SYNCHRONIZED else 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun createMethod(flags: Int, signature: JvmMethodGenericSignature): MethodVisitor =
|
|
||||||
classCodegen.visitor.newMethod(
|
|
||||||
irFunction.OtherOrigin,
|
|
||||||
flags,
|
|
||||||
signature.asmMethod.name,
|
|
||||||
signature.asmMethod.descriptor,
|
|
||||||
signature.genericsSignature.takeIf { flags.and(Opcodes.ACC_SYNTHETIC) == 0 },
|
|
||||||
getThrownExceptions(irFunction)?.toTypedArray()
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun getThrownExceptions(function: IrFunction): List<String>? {
|
private fun getThrownExceptions(function: IrFunction): List<String>? {
|
||||||
if (context.state.languageVersionSettings.supportsFeature(LanguageFeature.DoNotGenerateThrowsForDelegatedKotlinMembers) &&
|
if (context.state.languageVersionSettings.supportsFeature(LanguageFeature.DoNotGenerateThrowsForDelegatedKotlinMembers) &&
|
||||||
function.origin == IrDeclarationOrigin.DELEGATED_MEMBER
|
function.origin == IrDeclarationOrigin.DELEGATED_MEMBER
|
||||||
|
|||||||
+6
-27
@@ -37,7 +37,6 @@ import org.jetbrains.kotlin.psi.doNotAnalyze
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
import org.jetbrains.org.objectweb.asm.*
|
import org.jetbrains.org.objectweb.asm.*
|
||||||
@@ -97,32 +96,10 @@ class IrSourceCompilerForInline(
|
|||||||
override val lazySourceMapper: DefaultSourceMapper
|
override val lazySourceMapper: DefaultSourceMapper
|
||||||
get() = codegen.smapOverride ?: codegen.classCodegen.getOrCreateSourceMapper()
|
get() = codegen.smapOverride ?: codegen.classCodegen.getOrCreateSourceMapper()
|
||||||
|
|
||||||
private fun makeInlineNode(function: IrFunction, classCodegen: ClassCodegen, isLambda: Boolean): SMAPAndMethodNode {
|
|
||||||
var node: MethodNode? = null
|
|
||||||
val smap = if (isLambda)
|
|
||||||
codegen.context.getSourceMapper(codegen.classCodegen.irClass)
|
|
||||||
else
|
|
||||||
classCodegen.getOrCreateSourceMapper()
|
|
||||||
val functionCodegen = object : FunctionCodegen(function, classCodegen, codegen.takeIf { isLambda }) {
|
|
||||||
override fun createMethod(flags: Int, signature: JvmMethodGenericSignature): MethodVisitor {
|
|
||||||
val asmMethod = signature.asmMethod
|
|
||||||
node = MethodNode(
|
|
||||||
Opcodes.API_VERSION,
|
|
||||||
flags,
|
|
||||||
asmMethod.name.removeSuffix(FOR_INLINE_SUFFIX),
|
|
||||||
asmMethod.descriptor,
|
|
||||||
signature.genericsSignature,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
return wrapWithMaxLocalCalc(node!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
functionCodegen.generate(smap)
|
|
||||||
return SMAPAndMethodNode(node!!, SMAP(smap.resultMappings))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun generateLambdaBody(lambdaInfo: ExpressionLambda): SMAPAndMethodNode {
|
override fun generateLambdaBody(lambdaInfo: ExpressionLambda): SMAPAndMethodNode {
|
||||||
return makeInlineNode((lambdaInfo as IrExpressionLambdaImpl).function, codegen.classCodegen, true)
|
val smap = codegen.context.getSourceMapper(codegen.classCodegen.irClass)
|
||||||
|
val node = FunctionCodegen((lambdaInfo as IrExpressionLambdaImpl).function, codegen.classCodegen, codegen).generate(smap)
|
||||||
|
return SMAPAndMethodNode(node, SMAP(smap.resultMappings))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doCreateMethodNodeFromSource(
|
override fun doCreateMethodNodeFromSource(
|
||||||
@@ -141,7 +118,9 @@ class IrSourceCompilerForInline(
|
|||||||
} ?: callee
|
} ?: callee
|
||||||
else
|
else
|
||||||
callee
|
callee
|
||||||
return makeInlineNode(forInlineFunction, FakeClassCodegen(forInlineFunction, codegen.classCodegen), false)
|
val fakeCodegen = FakeClassCodegen(forInlineFunction, codegen.classCodegen)
|
||||||
|
val node = FunctionCodegen(forInlineFunction, fakeCodegen).generate()
|
||||||
|
return SMAPAndMethodNode(node, SMAP(fakeCodegen.getOrCreateSourceMapper().resultMappings))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hasFinallyBlocks() = data.hasFinallyBlocks()
|
override fun hasFinallyBlocks() = data.hasFinallyBlocks()
|
||||||
|
|||||||
Reference in New Issue
Block a user