JVM_IR: restore InnerClasses for objects in lambdas

This commit is contained in:
pyos
2020-03-19 11:13:20 +01:00
parent be87d5fab5
commit 186302d84e
7 changed files with 25 additions and 28 deletions
@@ -345,17 +345,6 @@ open class ClassCodegen protected constructor(
fun createLocalClassCodegen(klass: IrClass, parentFunction: IrFunction): ClassCodegen =
ClassCodegen(klass, context, this, parentFunction, withinInline = withinInline || parentFunction.isInline)
fun createClassCodegenForLambdaBody(parentClass: IrClass, lambda: IrFunction): ClassCodegen =
object : ClassCodegen(parentClass, context, parentFunction = parentFunction, withinInline = withinInline) {
override fun createClassBuilder(): ClassBuilder {
return object : AbstractClassBuilder() {
override fun getVisitor(): ClassVisitor {
TODO("Expect to be _not_ reached")
}
}
}
}
private fun generateField(field: IrField) {
if (field.origin == IrDeclarationOrigin.FAKE_OVERRIDE) return
@@ -109,7 +109,8 @@ class ExpressionCodegen(
override val frameMap: IrFrameMap,
val mv: InstructionAdapter,
val classCodegen: ClassCodegen,
val inlinedInto: ExpressionCodegen?
val inlinedInto: ExpressionCodegen?,
val smapOverride: DefaultSourceMapper?
) : IrElementVisitor<PromisedValue, BlockInfo>, BaseExpressionCodegen {
var finallyDepth = 0
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper
import org.jetbrains.kotlin.codegen.mangleNameIfNeeded
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.visitAnnotableParameterCount
@@ -38,7 +39,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
open class FunctionCodegen(
private val irFunction: IrFunction,
private val classCodegen: ClassCodegen,
private val inlinedInto: ExpressionCodegen? = null,
private val inlinedInto: ExpressionCodegen? = null
) {
val context = classCodegen.context
val state = classCodegen.state
@@ -47,14 +48,14 @@ open class FunctionCodegen(
classCodegen.createLocalClassCodegen(irFunction.continuationClass(), irFunction).also { it.generate() }
}
fun generate(): JvmMethodGenericSignature =
fun generate(smapOverride: DefaultSourceMapper? = null): JvmMethodGenericSignature =
try {
doGenerate()
doGenerate(smapOverride)
} catch (e: Throwable) {
throw RuntimeException("Exception while generating code for:\n${irFunction.dump()}", e)
}
private fun doGenerate(): JvmMethodGenericSignature {
private fun doGenerate(smapOverride: DefaultSourceMapper?): JvmMethodGenericSignature {
val signature = classCodegen.methodSignatureMapper.mapSignatureWithGeneric(irFunction)
val flags = calculateMethodFlags(irFunction.isStatic)
@@ -113,7 +114,8 @@ open class FunctionCodegen(
}
context.state.globalInlineContext.enterDeclaration(irFunction.suspendFunctionOriginal().descriptor)
try {
ExpressionCodegen(irFunction, signature, frameMap, InstructionAdapter(methodVisitor), classCodegen, inlinedInto).generate()
val adapter = InstructionAdapter(methodVisitor)
ExpressionCodegen(irFunction, signature, frameMap, adapter, classCodegen, inlinedInto, smapOverride).generate()
} finally {
context.state.globalInlineContext.exitDeclaration()
}
@@ -95,10 +95,14 @@ class IrSourceCompilerForInline(
}
override val lazySourceMapper: DefaultSourceMapper
get() = 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
@@ -113,13 +117,12 @@ class IrSourceCompilerForInline(
return wrapWithMaxLocalCalc(node!!)
}
}
functionCodegen.generate()
return SMAPAndMethodNode(node!!, SMAP(classCodegen.getOrCreateSourceMapper().resultMappings))
functionCodegen.generate(smap)
return SMAPAndMethodNode(node!!, SMAP(smap.resultMappings))
}
override fun generateLambdaBody(lambdaInfo: ExpressionLambda): SMAPAndMethodNode {
val function = (lambdaInfo as IrExpressionLambdaImpl).function
return makeInlineNode(function, codegen.classCodegen.createClassCodegenForLambdaBody(codegen.classCodegen.irClass, function), true)
return makeInlineNode((lambdaInfo as IrExpressionLambdaImpl).function, codegen.classCodegen, true)
}
override fun doCreateMethodNodeFromSource(
@@ -151,7 +154,7 @@ class IrSourceCompilerForInline(
override fun createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn(finallyNode: MethodNode, curFinallyDepth: Int) =
ExpressionCodegen(
codegen.irFunction, codegen.signature, codegen.frameMap, InstructionAdapter(finallyNode), codegen.classCodegen,
codegen.inlinedInto
codegen.inlinedInto, codegen.smapOverride
).also {
it.finallyDepth = curFinallyDepth
}