KAPT+IR: Generate LVT in kapt mode

This commit is contained in:
Mikhael Bogdanov
2022-03-14 11:51:40 +01:00
committed by Space
parent 0153f5d92a
commit 093b1bebb0
7 changed files with 103 additions and 101 deletions
@@ -221,29 +221,34 @@ class ExpressionCodegen(
fun generate() {
mv.visitCode()
val startLabel = markNewLabel()
if (irFunction.isMultifileBridge()) {
// Multifile bridges need to have line number 1 to be filtered out by the intellij debugging filters.
mv.visitLineNumber(1, startLabel)
}
val info = BlockInfo()
val body = irFunction.body
?: error("Function has no body: ${irFunction.render()}")
generateNonNullAssertions()
generateFakeContinuationConstructorIfNeeded()
val result = body.accept(this, info)
// If this function has an expression body, return the result of that expression.
// Otherwise, if it does not end in a return statement, it must be void-returning,
// and an explicit return instruction at the end is still required to pass validation.
if (body !is IrStatementContainer || body.statements.lastOrNull() !is IrReturn) {
// Allow setting a breakpoint on the closing brace of a void-returning function
// without an explicit return, or the `class Something(` line of a primary constructor.
if (irFunction.origin != JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER) {
irFunction.markLineNumber(startOffset = irFunction is IrConstructor && irFunction.isPrimary)
if (context.state.classBuilderMode.generateBodies) {
if (irFunction.isMultifileBridge()) {
// Multifile bridges need to have line number 1 to be filtered out by the intellij debugging filters.
mv.visitLineNumber(1, startLabel)
}
val (returnType, returnIrType) = irFunction.returnAsmAndIrTypes()
result.materializeAt(returnType, returnIrType)
mv.areturn(returnType)
val body = irFunction.body
?: error("Function has no body: ${irFunction.render()}")
generateNonNullAssertions()
generateFakeContinuationConstructorIfNeeded()
val result = body.accept(this, info)
// If this function has an expression body, return the result of that expression.
// Otherwise, if it does not end in a return statement, it must be void-returning,
// and an explicit return instruction at the end is still required to pass validation.
if (body !is IrStatementContainer || body.statements.lastOrNull() !is IrReturn) {
// Allow setting a breakpoint on the closing brace of a void-returning function
// without an explicit return, or the `class Something(` line of a primary constructor.
if (irFunction.origin != JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER) {
irFunction.markLineNumber(startOffset = irFunction is IrConstructor && irFunction.isPrimary)
}
val (returnType, returnIrType) = irFunction.returnAsmAndIrTypes()
result.materializeAt(returnType, returnIrType)
mv.areturn(returnType)
}
} else {
mv.aconst(null)
mv.athrow()
}
val endLabel = markNewLabel()
writeLocalVariablesInTable(info, endLabel)
@@ -104,7 +104,7 @@ class FunctionCodegen(private val irFunction: IrFunction, private val classCodeg
// `$$forInline` versions of suspend functions have the same bodies as the originals, but with different
// name/flags/annotations and with no state machine.
val notForInline = irFunction.suspendForInlineToOriginal()
val smap = if (!context.state.classBuilderMode.generateBodies || flags.and(Opcodes.ACC_ABSTRACT) != 0 || irFunction.isExternal) {
val smap = if (flags.and(Opcodes.ACC_ABSTRACT) != 0 || irFunction.isExternal) {
generateAnnotationDefaultValueIfNeeded(methodVisitor)
SMAP(listOf())
} else if (notForInline != null) {