Initial support of non-local return in IR
This commit is contained in:
+30
-8
@@ -16,10 +16,7 @@ import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.*
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen.putReifiedOperationMarkerIfTypeIsReifiedParameter
|
||||
import org.jetbrains.kotlin.codegen.StackValue.*
|
||||
import org.jetbrains.kotlin.codegen.inline.NameGenerator
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
|
||||
import org.jetbrains.kotlin.codegen.inline.TypeParameterMappings
|
||||
import org.jetbrains.kotlin.codegen.inline.*
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysTrueIfeq
|
||||
@@ -674,15 +671,40 @@ class ExpressionCodegen(
|
||||
}
|
||||
|
||||
override fun visitReturn(expression: IrReturn, data: BlockInfo): StackValue {
|
||||
val value = expression.value.apply {
|
||||
gen(this, returnType, data)
|
||||
val owner = expression.returnTargetSymbol.owner
|
||||
val isNonLocalReturn = owner != irFunction
|
||||
if (isNonLocalReturn && state.isInlineDisabled) {
|
||||
//TODO: state.diagnostics.report(Errors.NON_LOCAL_RETURN_IN_DISABLED_INLINE.on(expression))
|
||||
genThrow(
|
||||
mv, "java/lang/UnsupportedOperationException",
|
||||
"Non-local returns are not allowed with inlining disabled"
|
||||
)
|
||||
return none()
|
||||
}
|
||||
|
||||
val actualReturn =
|
||||
if (isNonLocalReturn) {
|
||||
typeMapper.mapReturnType(owner.descriptor)
|
||||
} else {
|
||||
returnType
|
||||
}
|
||||
|
||||
expression.value.apply {
|
||||
gen(this, actualReturn, data)
|
||||
}
|
||||
|
||||
val afterReturnLabel = Label()
|
||||
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data)
|
||||
generateFinallyBlocksIfNeeded(actualReturn, afterReturnLabel, data)
|
||||
|
||||
expression.markLineNumber(startOffset = true)
|
||||
mv.areturn(returnType)
|
||||
if (isNonLocalReturn) {
|
||||
val nonLocalReturnType = typeMapper.mapReturnType(owner.descriptor)
|
||||
val labelName = (owner as IrFunction).name.asString()
|
||||
generateGlobalReturnFlag(mv, labelName)
|
||||
mv.areturn(nonLocalReturnType)
|
||||
} else {
|
||||
mv.areturn(actualReturn)
|
||||
}
|
||||
mv.mark(afterReturnLabel)
|
||||
mv.nop()/*TODO check RESTORE_STACK_IN_TRY_CATCH processor*/
|
||||
return expression.onStack
|
||||
|
||||
+1
-2
@@ -115,8 +115,7 @@ class IrExpressionLambdaImpl(
|
||||
) : ExpressionLambda(typeMapper, isCrossInline), IrExpressionLambda {
|
||||
|
||||
override fun isReturnFromMe(labelName: String): Boolean {
|
||||
//TODO("not implemented")
|
||||
return false
|
||||
return false //always false
|
||||
}
|
||||
|
||||
override val lambdaClassType: Type = Type.getObjectType("test123")
|
||||
|
||||
+2
-3
@@ -88,7 +88,7 @@ class IrSourceCompilerForInline(
|
||||
asmMethod: Method
|
||||
): SMAPAndMethodNode {
|
||||
assert(callableDescriptor == callElement.descriptor.original)
|
||||
val irFunction = ((callElement as IrCall).symbol.owner as IrFunction).let { irFunction ->
|
||||
val irFunction = (callElement as IrCall).symbol.owner.let { irFunction ->
|
||||
if (!callDefault) irFunction
|
||||
else {
|
||||
/*TODO: get rid of hack*/
|
||||
@@ -160,8 +160,7 @@ class IrSourceCompilerForInline(
|
||||
get() = callElement.descriptor as FunctionDescriptor
|
||||
|
||||
override fun getContextLabels(): Set<String> {
|
||||
//TODO
|
||||
return emptySet()
|
||||
return setOf(codegen.irFunction.name.asString())
|
||||
}
|
||||
|
||||
override fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) {
|
||||
|
||||
Reference in New Issue
Block a user