Generate synthetic instructions in loops to support non standart stack transformation
This commit is contained in:
+24
-8
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
|||||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
|
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
|
||||||
import org.jetbrains.kotlin.codegen.inline.TypeParameterMappings
|
import org.jetbrains.kotlin.codegen.inline.TypeParameterMappings
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty
|
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty
|
||||||
|
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fixStackAndJump
|
import org.jetbrains.kotlin.codegen.pseudoInsns.fixStackAndJump
|
||||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -111,21 +112,31 @@ class ExpressionCodegen(
|
|||||||
fun generate() {
|
fun generate() {
|
||||||
mv.visitCode()
|
mv.visitCode()
|
||||||
val info = BlockInfo.create()
|
val info = BlockInfo.create()
|
||||||
val result = irFunction.body?.accept(this, info)
|
val result = irFunction.body!!.accept(this, info)
|
||||||
// result?.apply {
|
|
||||||
// coerce(this.type, irFunction.body!!.as)
|
|
||||||
// }
|
|
||||||
val returnType = typeMapper.mapReturnType(irFunction.descriptor)
|
val returnType = typeMapper.mapReturnType(irFunction.descriptor)
|
||||||
if (returnType == Type.VOID_TYPE) {
|
if (irFunction.body is IrExpressionBody) {
|
||||||
//for implicit return
|
|
||||||
mv.areturn(Type.VOID_TYPE)
|
|
||||||
} else if (irFunction.body is IrExpressionBody) {
|
|
||||||
mv.areturn(returnType)
|
mv.areturn(returnType)
|
||||||
|
//TODO merge branch inside next one
|
||||||
|
} else if (!endsWithReturn(irFunction.body!!)) {
|
||||||
|
if (returnType == Type.VOID_TYPE) {
|
||||||
|
mv.areturn(returnType)
|
||||||
|
} else {
|
||||||
|
StackValue.none().put(returnType, null, mv)
|
||||||
|
mv.areturn(returnType)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
writeLocalVariablesInTable(info)
|
writeLocalVariablesInTable(info)
|
||||||
mv.visitEnd()
|
mv.visitEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun endsWithReturn(body: IrBody): Boolean {
|
||||||
|
val lastStatement = if (body is IrStatementContainer) {
|
||||||
|
body.statements.lastOrNull() ?: body
|
||||||
|
} else body
|
||||||
|
return lastStatement is IrReturn
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitBlockBody(body: IrBlockBody, data: BlockInfo): StackValue {
|
override fun visitBlockBody(body: IrBlockBody, data: BlockInfo): StackValue {
|
||||||
return body.statements.fold(none()) { _, exp ->
|
return body.statements.fold(none()) { _, exp ->
|
||||||
exp.accept(this, data)
|
exp.accept(this, data)
|
||||||
@@ -650,6 +661,8 @@ class ExpressionCodegen(
|
|||||||
if (!(condition is IrConst<*> && condition.value == true)) {
|
if (!(condition is IrConst<*> && condition.value == true)) {
|
||||||
gen(condition, data)
|
gen(condition, data)
|
||||||
BranchedValue.condJump(StackValue.onStack(condition.asmType), endLabel, true, mv)
|
BranchedValue.condJump(StackValue.onStack(condition.asmType), endLabel, true, mv)
|
||||||
|
} else {
|
||||||
|
mv.fakeAlwaysFalseIfeq(endLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
with(LoopInfo(loop, continueLabel, endLabel)) {
|
with(LoopInfo(loop, continueLabel, endLabel)) {
|
||||||
@@ -708,6 +721,9 @@ class ExpressionCodegen(
|
|||||||
val endLabel = Label()
|
val endLabel = Label()
|
||||||
val continueLabel = Label()
|
val continueLabel = Label()
|
||||||
|
|
||||||
|
mv.fakeAlwaysFalseIfeq(continueLabel)
|
||||||
|
mv.fakeAlwaysFalseIfeq(endLabel)
|
||||||
|
|
||||||
with(LoopInfo(loop, continueLabel, endLabel)) {
|
with(LoopInfo(loop, continueLabel, endLabel)) {
|
||||||
data.addInfo(this)
|
data.addInfo(this)
|
||||||
loop.body?.apply {
|
loop.body?.apply {
|
||||||
|
|||||||
Reference in New Issue
Block a user