Simplify code for specialized BranchedValues
This commit is contained in:
+72
-172
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen
|
|||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
|
||||||
@@ -27,7 +26,7 @@ abstract class NumberLikeCompare(
|
|||||||
left: StackValue,
|
left: StackValue,
|
||||||
right: StackValue,
|
right: StackValue,
|
||||||
operandType: Type,
|
operandType: Type,
|
||||||
protected val opToken: IElementType
|
private val opToken: IElementType
|
||||||
) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) {
|
) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) {
|
||||||
override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int =
|
override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int =
|
||||||
NumberCompare.patchOpcode(opcode, v, opToken, operandType)
|
NumberCompare.patchOpcode(opcode, v, opToken, operandType)
|
||||||
@@ -130,102 +129,51 @@ class BoxedToPrimitiveEquality private constructor(
|
|||||||
private val boxedType = arg1.type
|
private val boxedType = arg1.type
|
||||||
|
|
||||||
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
||||||
if (jumpIfFalse) {
|
if (arg2!!.canHaveSideEffects()) {
|
||||||
jumpIfFalse(v, jumpLabel)
|
val tmp = frameMap.enterTemp(operandType)
|
||||||
|
doJump(
|
||||||
|
v, jumpLabel, jumpIfFalse,
|
||||||
|
{
|
||||||
|
arg1.put(boxedType, v)
|
||||||
|
arg2.put(operandType, v)
|
||||||
|
v.store(tmp, operandType)
|
||||||
|
},
|
||||||
|
{ v.load(tmp, operandType) }
|
||||||
|
)
|
||||||
|
frameMap.leaveTemp(operandType)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
jumpIfTrue(v, jumpLabel)
|
doJump(
|
||||||
|
v, jumpLabel, jumpIfFalse,
|
||||||
|
{ arg1.put(boxedType, v) },
|
||||||
|
{ arg2.put(operandType, v) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun jumpIfTrue(v: InstructionAdapter, jumpLabel: Label) {
|
private inline fun doJump(
|
||||||
if (arg2!!.canHaveSideEffects()) {
|
v: InstructionAdapter,
|
||||||
jumpIfTrueWithPossibleSideEffects(v, jumpLabel)
|
jumpLabel: Label,
|
||||||
return
|
jumpIfFalse: Boolean,
|
||||||
}
|
putArg1: () -> Unit,
|
||||||
|
putArg2: () -> Unit
|
||||||
val notNullLabel = Label()
|
) {
|
||||||
val endLabel = Label()
|
|
||||||
arg1.put(boxedType, v)
|
|
||||||
AsmUtil.dup(v, boxedType)
|
|
||||||
v.ifnonnull(notNullLabel)
|
|
||||||
|
|
||||||
AsmUtil.pop(v, boxedType)
|
|
||||||
v.goTo(endLabel)
|
|
||||||
|
|
||||||
v.mark(notNullLabel)
|
|
||||||
coerce(boxedType, operandType, v)
|
|
||||||
arg2.put(operandType, v)
|
|
||||||
v.visitJumpInsn(patchOpcode(negatedOperations[opcode]!!, v), jumpLabel)
|
|
||||||
|
|
||||||
v.mark(endLabel)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun jumpIfTrueWithPossibleSideEffects(v: InstructionAdapter, jumpLabel: Label) {
|
|
||||||
val notNullLabel = Label()
|
val notNullLabel = Label()
|
||||||
val endLabel = Label()
|
val endLabel = Label()
|
||||||
|
|
||||||
arg1.put(boxedType, v)
|
putArg1()
|
||||||
arg2!!.put(operandType, v)
|
|
||||||
|
|
||||||
val tempArg2 = frameMap.enterTemp(operandType)
|
|
||||||
|
|
||||||
v.store(tempArg2, operandType)
|
|
||||||
AsmUtil.dup(v, boxedType)
|
AsmUtil.dup(v, boxedType)
|
||||||
v.ifnonnull(notNullLabel)
|
v.ifnonnull(notNullLabel)
|
||||||
|
|
||||||
AsmUtil.pop(v, boxedType)
|
AsmUtil.pop(v, boxedType)
|
||||||
v.goTo(endLabel)
|
if (jumpIfFalse) v.goTo(jumpLabel) else v.goTo(endLabel)
|
||||||
|
|
||||||
v.mark(notNullLabel)
|
v.mark(notNullLabel)
|
||||||
coerce(boxedType, operandType, v)
|
coerce(boxedType, operandType, v)
|
||||||
v.load(tempArg2, operandType)
|
putArg2()
|
||||||
v.visitJumpInsn(patchOpcode(negatedOperations[opcode]!!, v), jumpLabel)
|
v.visitJumpInsn(patchOpcode(if (jumpIfFalse) opcode else negatedOperations[opcode]!!, v), jumpLabel)
|
||||||
|
|
||||||
frameMap.leaveTemp(operandType)
|
|
||||||
v.mark(endLabel)
|
v.mark(endLabel)
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun jumpIfFalse(v: InstructionAdapter, jumpLabel: Label) {
|
|
||||||
if (arg2!!.canHaveSideEffects()) {
|
|
||||||
jumpIfFalseWithPossibleSideEffects(v, jumpLabel)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val notNullLabel = Label()
|
|
||||||
arg1.put(boxedType, v)
|
|
||||||
AsmUtil.dup(v, boxedType)
|
|
||||||
v.ifnonnull(notNullLabel)
|
|
||||||
|
|
||||||
AsmUtil.pop(v, boxedType)
|
|
||||||
v.goTo(jumpLabel)
|
|
||||||
|
|
||||||
v.mark(notNullLabel)
|
|
||||||
coerce(boxedType, operandType, v)
|
|
||||||
arg2.put(operandType, v)
|
|
||||||
v.visitJumpInsn(patchOpcode(opcode, v), jumpLabel)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun jumpIfFalseWithPossibleSideEffects(v: InstructionAdapter, jumpLabel: Label) {
|
|
||||||
val notNullLabel = Label()
|
|
||||||
|
|
||||||
arg1.put(boxedType, v)
|
|
||||||
arg2!!.put(operandType, v)
|
|
||||||
val tempArg2 = frameMap.enterTemp(operandType)
|
|
||||||
v.store(tempArg2, operandType)
|
|
||||||
AsmUtil.dup(v, boxedType)
|
|
||||||
v.ifnonnull(notNullLabel)
|
|
||||||
|
|
||||||
AsmUtil.pop(v, boxedType)
|
|
||||||
v.goTo(jumpLabel)
|
|
||||||
|
|
||||||
v.mark(notNullLabel)
|
|
||||||
coerce(boxedType, operandType, v)
|
|
||||||
v.load(tempArg2, operandType)
|
|
||||||
v.visitJumpInsn(patchOpcode(opcode, v), jumpLabel)
|
|
||||||
|
|
||||||
frameMap.leaveTemp(operandType)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -254,59 +202,53 @@ class BoxedToPrimitiveEquality private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class PrimitiveToSomethingEquality
|
||||||
|
protected constructor(
|
||||||
|
leftPrimitive: StackValue,
|
||||||
|
right: StackValue,
|
||||||
|
primitiveType: Type
|
||||||
|
) : NumberLikeCompare(leftPrimitive, right, primitiveType, KtTokens.EQEQ) {
|
||||||
|
protected val primitiveType = leftPrimitive.type
|
||||||
|
protected val rightType = right.type
|
||||||
|
|
||||||
|
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
||||||
|
val notNullLabel = Label()
|
||||||
|
val endLabel = Label()
|
||||||
|
|
||||||
|
arg1.put(primitiveType, v)
|
||||||
|
arg2!!.put(rightType, v)
|
||||||
|
AsmUtil.dup(v, rightType)
|
||||||
|
jumpIfCanCompareTopWithPrimitive(v, notNullLabel)
|
||||||
|
|
||||||
|
AsmUtil.pop(v, rightType)
|
||||||
|
AsmUtil.pop(v, primitiveType)
|
||||||
|
if (jumpIfFalse) v.goTo(jumpLabel) else v.goTo(endLabel)
|
||||||
|
|
||||||
|
v.mark(notNullLabel)
|
||||||
|
coerceRightToPrimitive(v)
|
||||||
|
v.visitJumpInsn(patchOpcode(if (jumpIfFalse) opcode else negatedOperations[opcode]!!, v), jumpLabel)
|
||||||
|
|
||||||
|
v.mark(endLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun jumpIfCanCompareTopWithPrimitive(v: InstructionAdapter, label: Label)
|
||||||
|
protected abstract fun coerceRightToPrimitive(v: InstructionAdapter)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class PrimitiveToBoxedEquality private constructor(
|
class PrimitiveToBoxedEquality private constructor(
|
||||||
leftPrimitive: StackValue,
|
leftPrimitive: StackValue,
|
||||||
rightBoxed: StackValue,
|
rightBoxed: StackValue,
|
||||||
primitiveType: Type
|
primitiveType: Type
|
||||||
) : NumberLikeCompare(leftPrimitive, rightBoxed, primitiveType, KtTokens.EQEQ) {
|
) : PrimitiveToSomethingEquality(leftPrimitive, rightBoxed, primitiveType) {
|
||||||
private val primitiveType = leftPrimitive.type
|
|
||||||
private val boxedType = rightBoxed.type
|
private val boxedType = rightBoxed.type
|
||||||
|
|
||||||
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
override fun jumpIfCanCompareTopWithPrimitive(v: InstructionAdapter, label: Label) {
|
||||||
if (jumpIfFalse) {
|
v.ifnonnull(label)
|
||||||
jumpIfFalse(v, jumpLabel)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
jumpIfTrue(v, jumpLabel)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun jumpIfFalse(v: InstructionAdapter, jumpLabel: Label) {
|
override fun coerceRightToPrimitive(v: InstructionAdapter) {
|
||||||
val notNullLabel = Label()
|
|
||||||
|
|
||||||
arg1.put(primitiveType, v)
|
|
||||||
arg2!!.put(boxedType, v)
|
|
||||||
AsmUtil.dup(v, boxedType)
|
|
||||||
v.ifnonnull(notNullLabel)
|
|
||||||
|
|
||||||
AsmUtil.pop(v, boxedType)
|
|
||||||
AsmUtil.pop(v, primitiveType)
|
|
||||||
v.goTo(jumpLabel)
|
|
||||||
|
|
||||||
v.mark(notNullLabel)
|
|
||||||
coerce(boxedType, primitiveType, v)
|
coerce(boxedType, primitiveType, v)
|
||||||
v.visitJumpInsn(patchOpcode(opcode, v), jumpLabel)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun jumpIfTrue(v: InstructionAdapter, jumpLabel: Label) {
|
|
||||||
val notNullLabel = Label()
|
|
||||||
val endLabel = Label()
|
|
||||||
|
|
||||||
arg1.put(primitiveType, v)
|
|
||||||
arg2!!.put(boxedType, v)
|
|
||||||
AsmUtil.dup(v, boxedType)
|
|
||||||
v.ifnonnull(notNullLabel)
|
|
||||||
|
|
||||||
AsmUtil.pop(v, boxedType)
|
|
||||||
AsmUtil.pop(v, primitiveType)
|
|
||||||
v.goTo(endLabel)
|
|
||||||
|
|
||||||
v.mark(notNullLabel)
|
|
||||||
coerce(boxedType, primitiveType, v)
|
|
||||||
v.visitJumpInsn(patchOpcode(negatedOperations[opcode]!!, v), jumpLabel)
|
|
||||||
|
|
||||||
v.mark(endLabel)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -333,59 +275,17 @@ class PrimitiveToObjectEquality private constructor(
|
|||||||
leftPrimitive: StackValue,
|
leftPrimitive: StackValue,
|
||||||
rightObject: StackValue,
|
rightObject: StackValue,
|
||||||
primitiveType: Type
|
primitiveType: Type
|
||||||
) : NumberLikeCompare(leftPrimitive, rightObject, primitiveType, KtTokens.EQEQ) {
|
) : PrimitiveToSomethingEquality(leftPrimitive, rightObject, primitiveType) {
|
||||||
private val primitiveType = leftPrimitive.type
|
|
||||||
private val objectType = rightObject.type
|
|
||||||
private val boxedType = AsmUtil.boxType(primitiveType)
|
private val boxedType = AsmUtil.boxType(primitiveType)
|
||||||
|
|
||||||
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
override fun jumpIfCanCompareTopWithPrimitive(v: InstructionAdapter, label: Label) {
|
||||||
if (jumpIfFalse) {
|
v.instanceOf(boxedType)
|
||||||
jumpIfFalse(v, jumpLabel)
|
v.ifne(label)
|
||||||
}
|
|
||||||
else {
|
|
||||||
jumpIfTrue(v, jumpLabel)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun jumpIfFalse(v: InstructionAdapter, jumpLabel: Label) {
|
override fun coerceRightToPrimitive(v: InstructionAdapter) {
|
||||||
val isBoxedLabel = Label()
|
coerce(rightType, boxedType, v)
|
||||||
|
|
||||||
arg1.put(primitiveType, v)
|
|
||||||
arg2!!.put(objectType, v)
|
|
||||||
AsmUtil.dup(v, objectType)
|
|
||||||
v.instanceOf(boxedType)
|
|
||||||
v.ifne(isBoxedLabel)
|
|
||||||
|
|
||||||
AsmUtil.pop(v, objectType)
|
|
||||||
AsmUtil.pop(v, primitiveType)
|
|
||||||
v.goTo(jumpLabel)
|
|
||||||
|
|
||||||
v.mark(isBoxedLabel)
|
|
||||||
coerce(objectType, boxedType, v)
|
|
||||||
coerce(boxedType, primitiveType, v)
|
coerce(boxedType, primitiveType, v)
|
||||||
v.visitJumpInsn(patchOpcode(opcode, v), jumpLabel)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun jumpIfTrue(v: InstructionAdapter, jumpLabel: Label) {
|
|
||||||
val isBoxedLabel = Label()
|
|
||||||
val endLabel = Label()
|
|
||||||
|
|
||||||
arg1.put(primitiveType, v)
|
|
||||||
arg2!!.put(objectType, v)
|
|
||||||
AsmUtil.dup(v, objectType)
|
|
||||||
v.instanceOf(boxedType)
|
|
||||||
v.ifne(isBoxedLabel)
|
|
||||||
|
|
||||||
AsmUtil.pop(v, objectType)
|
|
||||||
AsmUtil.pop(v, primitiveType)
|
|
||||||
v.goTo(endLabel)
|
|
||||||
|
|
||||||
v.mark(isBoxedLabel)
|
|
||||||
coerce(objectType, boxedType, v)
|
|
||||||
coerce(boxedType, primitiveType, v)
|
|
||||||
v.visitJumpInsn(patchOpcode(negatedOperations[opcode]!!, v), jumpLabel)
|
|
||||||
|
|
||||||
v.mark(endLabel)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
Reference in New Issue
Block a user