IR: use the correct descriptor for the booleanNotSymbol creation
NOTE corresponding function now has a dispatch receiver instead of a single argument
This commit is contained in:
@@ -232,7 +232,6 @@ message IrCall {
|
||||
enum Primitive {
|
||||
NOT_PRIMITIVE = 1;
|
||||
NULLARY = 2;
|
||||
UNARY = 3;
|
||||
BINARY = 4;
|
||||
}
|
||||
required Primitive kind = 1;
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ fun IrBuilderWithScope.irIfThen(condition: IrExpression, thenPart: IrExpression)
|
||||
}
|
||||
|
||||
fun IrBuilderWithScope.irNot(arg: IrExpression) =
|
||||
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL, arg)
|
||||
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNotSymbol, context.irBuiltIns.booleanType, IrStatementOrigin.EXCL, arg)
|
||||
|
||||
fun IrBuilderWithScope.irThrow(arg: IrExpression) =
|
||||
IrThrowImpl(startOffset, endOffset, context.irBuiltIns.nothingType, arg)
|
||||
|
||||
-2
@@ -261,8 +261,6 @@ abstract class IrModuleDeserializer(
|
||||
)
|
||||
KotlinIr.IrCall.Primitive.NULLARY ->
|
||||
IrNullaryPrimitiveImpl(start, end, type, null, symbol)
|
||||
KotlinIr.IrCall.Primitive.UNARY ->
|
||||
IrUnaryPrimitiveImpl(start, end, type, null, symbol)
|
||||
KotlinIr.IrCall.Primitive.BINARY ->
|
||||
IrBinaryPrimitiveImpl(start, end, type, null, symbol)
|
||||
else -> TODO("Unexpected primitive IrCall.")
|
||||
|
||||
-3
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBinaryPrimitiveImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrNullaryPrimitiveImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrUnaryPrimitiveImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
@@ -350,8 +349,6 @@ open class IrModuleSerializer(
|
||||
private fun irCallToPrimitiveKind(call: IrCall): KotlinIr.IrCall.Primitive = when (call) {
|
||||
is IrNullaryPrimitiveImpl
|
||||
-> KotlinIr.IrCall.Primitive.NULLARY
|
||||
is IrUnaryPrimitiveImpl
|
||||
-> KotlinIr.IrCall.Primitive.UNARY
|
||||
is IrBinaryPrimitiveImpl
|
||||
-> KotlinIr.IrCall.Primitive.BINARY
|
||||
else
|
||||
|
||||
+1
-10
@@ -18015,14 +18015,10 @@ public final class KotlinIr {
|
||||
* <code>NULLARY = 2;</code>
|
||||
*/
|
||||
NULLARY(1, 2),
|
||||
/**
|
||||
* <code>UNARY = 3;</code>
|
||||
*/
|
||||
UNARY(2, 3),
|
||||
/**
|
||||
* <code>BINARY = 4;</code>
|
||||
*/
|
||||
BINARY(3, 4),
|
||||
BINARY(2, 4),
|
||||
;
|
||||
|
||||
/**
|
||||
@@ -18033,10 +18029,6 @@ public final class KotlinIr {
|
||||
* <code>NULLARY = 2;</code>
|
||||
*/
|
||||
public static final int NULLARY_VALUE = 2;
|
||||
/**
|
||||
* <code>UNARY = 3;</code>
|
||||
*/
|
||||
public static final int UNARY_VALUE = 3;
|
||||
/**
|
||||
* <code>BINARY = 4;</code>
|
||||
*/
|
||||
@@ -18049,7 +18041,6 @@ public final class KotlinIr {
|
||||
switch (value) {
|
||||
case 1: return NOT_PRIMITIVE;
|
||||
case 2: return NULLARY;
|
||||
case 3: return UNARY;
|
||||
case 4: return BINARY;
|
||||
default: return null;
|
||||
}
|
||||
|
||||
+1
-1
@@ -266,7 +266,7 @@ class BlockDecomposerTransformer(private val context: JsIrBackendContext) : IrEl
|
||||
val newLoopCondition = newCondition.statements.last() as IrExpression
|
||||
|
||||
val breakCond = JsIrBuilder.buildCall(booleanNotSymbol).apply {
|
||||
putValueArgument(0, newLoopCondition)
|
||||
dispatchReceiver = newLoopCondition
|
||||
}
|
||||
|
||||
newLoopBody.statements += JsIrBuilder.buildIfElse(unitType, breakCond, thenBlock)
|
||||
|
||||
+1
-1
@@ -233,7 +233,7 @@ class StateMachineBuilder(
|
||||
l.condition.acceptVoid(this)
|
||||
|
||||
transformLastExpression {
|
||||
val exitCond = JsIrBuilder.buildCall(booleanNotSymbol).apply { putValueArgument(0, it) }
|
||||
val exitCond = JsIrBuilder.buildCall(booleanNotSymbol).apply { dispatchReceiver = it }
|
||||
val irBreak = buildDispatchBlock(exit)
|
||||
JsIrBuilder.buildIfElse(unit, exitCond, irBreak)
|
||||
}
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ internal fun IrModuleFragment.replaceUnboundSymbols(context: JsIrBackendContext)
|
||||
val collector = DeclarationSymbolCollector()
|
||||
with(collector) {
|
||||
with(irBuiltins) {
|
||||
for (op in arrayOf(eqeqeqFun, eqeqFun, throwNpeFun, booleanNotFun, noWhenBranchMatchedExceptionFun) +
|
||||
for (op in arrayOf(eqeqeqFun, eqeqFun, throwNpeFun, noWhenBranchMatchedExceptionFun) +
|
||||
lessFunByOperandType.values +
|
||||
lessOrEqualFunByOperandType.values +
|
||||
greaterOrEqualFunByOperandType.values +
|
||||
|
||||
-30
@@ -35,17 +35,6 @@ internal val foldConstantLoweringPhase = makeIrFilePhase(
|
||||
* TODO: constant fields (e.g. Double.NaN)
|
||||
*/
|
||||
class FoldConstantLowering(private val context: JvmBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
||||
|
||||
/**
|
||||
* ID of an unary operator / method.
|
||||
*
|
||||
* An unary operator / method can be identified by its operand type (in full qualified name) and its name.
|
||||
*/
|
||||
private data class UnaryOp(
|
||||
val operandType: String,
|
||||
val operatorName: String
|
||||
)
|
||||
|
||||
/**
|
||||
* ID of an binary operator / method.
|
||||
*
|
||||
@@ -70,14 +59,8 @@ class FoldConstantLowering(private val context: JvmBackendContext) : IrElementTr
|
||||
private val BOOLEAN = PrimitiveType<Boolean>("Boolean")
|
||||
private val STRING = PrimitiveType<String>("String")
|
||||
|
||||
private val UNARY_OP_TO_EVALUATOR = HashMap<UnaryOp, Function1<Any?, Any>>()
|
||||
private val BINARY_OP_TO_EVALUATOR = HashMap<BinaryOp, Function2<Any?, Any?, Any>>()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T> registerBuiltinUnaryOp(operandType: PrimitiveType<T>, operatorName: String, f: (T) -> Any) {
|
||||
UNARY_OP_TO_EVALUATOR[UnaryOp(operandType.name, operatorName)] = f as Function1<Any?, Any>
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T> registerBuiltinBinaryOp(operandType: PrimitiveType<T>, operatorName: String, f: (T, T) -> Any) {
|
||||
BINARY_OP_TO_EVALUATOR[BinaryOp(operandType.name, operandType.name, operatorName)] = f as Function2<Any?, Any?, Any>
|
||||
@@ -85,8 +68,6 @@ class FoldConstantLowering(private val context: JvmBackendContext) : IrElementTr
|
||||
|
||||
init {
|
||||
// IrBuiltins
|
||||
registerBuiltinUnaryOp(BOOLEAN, IrBuiltIns.OperatorNames.NOT) { !it }
|
||||
|
||||
registerBuiltinBinaryOp(DOUBLE, IrBuiltIns.OperatorNames.LESS) { a, b -> a < b }
|
||||
registerBuiltinBinaryOp(DOUBLE, IrBuiltIns.OperatorNames.LESS_OR_EQUAL) { a, b -> a <= b }
|
||||
registerBuiltinBinaryOp(DOUBLE, IrBuiltIns.OperatorNames.GREATER) { a, b -> a > b }
|
||||
@@ -138,16 +119,6 @@ class FoldConstantLowering(private val context: JvmBackendContext) : IrElementTr
|
||||
return buildIrConstant(call, evaluated)
|
||||
}
|
||||
|
||||
private fun tryFoldingBuiltinUnaryOps(call: IrCall): IrExpression {
|
||||
if (call.symbol.owner.origin != IrDeclarationOrigin.IR_BUILTINS_STUB)
|
||||
return call
|
||||
|
||||
val operand = call.getValueArgument(0) as? IrConst<*> ?: return call
|
||||
val evaluator = UNARY_OP_TO_EVALUATOR[UnaryOp(operand.kind.toString(), call.symbol.owner.name.toString())] ?: return call
|
||||
|
||||
return buildIrConstant(call, evaluator(operand.value!!))
|
||||
}
|
||||
|
||||
private fun tryFoldingBinaryOps(call: IrCall): IrExpression {
|
||||
val lhs = call.dispatchReceiver as? IrConst<*> ?: return call
|
||||
val rhs = call.getValueArgument(0) as? IrConst<*> ?: return call
|
||||
@@ -201,7 +172,6 @@ class FoldConstantLowering(private val context: JvmBackendContext) : IrElementTr
|
||||
expression.extensionReceiver != null -> expression
|
||||
expression.dispatchReceiver != null && expression.valueArgumentsCount == 0 -> tryFoldingUnaryOps(expression)
|
||||
expression.dispatchReceiver != null && expression.valueArgumentsCount == 1 -> tryFoldingBinaryOps(expression)
|
||||
expression.dispatchReceiver == null && expression.valueArgumentsCount == 1 -> tryFoldingBuiltinUnaryOps(expression)
|
||||
expression.dispatchReceiver == null && expression.valueArgumentsCount == 2 -> tryFoldingBuiltinBinaryOps(expression)
|
||||
else -> expression
|
||||
}
|
||||
|
||||
+7
-4
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.buildStatement
|
||||
import org.jetbrains.kotlin.ir.builders.irIfThenMaybeElse
|
||||
import org.jetbrains.kotlin.ir.builders.primitiveOp1
|
||||
import org.jetbrains.kotlin.ir.builders.whenComma
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
@@ -218,10 +219,11 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
irSubject.defaultLoad()
|
||||
)
|
||||
return if (ktCondition.isNegated)
|
||||
IrUnaryPrimitiveImpl(
|
||||
primitiveOp1(
|
||||
ktCondition.startOffsetSkippingComments, ktCondition.endOffset,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
context.irBuiltIns.booleanType,
|
||||
IrStatementOrigin.EXCL, context.irBuiltIns.booleanNotSymbol,
|
||||
IrStatementOrigin.EXCL,
|
||||
irInstanceOf
|
||||
)
|
||||
else
|
||||
@@ -237,10 +239,11 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
IrStatementOrigin.IN ->
|
||||
irInCall
|
||||
IrStatementOrigin.NOT_IN ->
|
||||
IrUnaryPrimitiveImpl(
|
||||
primitiveOp1(
|
||||
ktCondition.startOffsetSkippingComments, ktCondition.endOffset,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
context.irBuiltIns.booleanType,
|
||||
IrStatementOrigin.EXCL, context.irBuiltIns.booleanNotSymbol,
|
||||
IrStatementOrigin.EXCL,
|
||||
irInCall
|
||||
)
|
||||
else -> throw AssertionError("Expected 'in' or '!in', got $inOperator")
|
||||
|
||||
+6
-6
@@ -241,11 +241,11 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
IrStatementOrigin.IN ->
|
||||
irContainsCall
|
||||
IrStatementOrigin.NOT_IN ->
|
||||
IrUnaryPrimitiveImpl(
|
||||
primitiveOp1(
|
||||
expression.startOffsetSkippingComments, expression.endOffset,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
context.irBuiltIns.booleanType,
|
||||
IrStatementOrigin.NOT_IN,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irContainsCall
|
||||
)
|
||||
else ->
|
||||
@@ -272,11 +272,11 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
IrStatementOrigin.EQEQEQ ->
|
||||
irIdentityEquals
|
||||
IrStatementOrigin.EXCLEQEQ ->
|
||||
IrUnaryPrimitiveImpl(
|
||||
primitiveOp1(
|
||||
expression.startOffsetSkippingComments, expression.endOffset,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
context.irBuiltIns.booleanType,
|
||||
IrStatementOrigin.EXCLEQEQ,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irIdentityEquals
|
||||
)
|
||||
else ->
|
||||
@@ -314,11 +314,11 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
IrStatementOrigin.EQEQ ->
|
||||
irEquals
|
||||
IrStatementOrigin.EXCLEQ ->
|
||||
IrUnaryPrimitiveImpl(
|
||||
primitiveOp1(
|
||||
expression.startOffsetSkippingComments, expression.endOffset,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
context.irBuiltIns.booleanType,
|
||||
IrStatementOrigin.EXCLEQ,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irEquals
|
||||
)
|
||||
else ->
|
||||
|
||||
@@ -195,7 +195,7 @@ fun IrBuilderWithScope.irEquals(arg1: IrExpression, arg2: IrExpression, origin:
|
||||
|
||||
fun IrBuilderWithScope.irNotEquals(arg1: IrExpression, arg2: IrExpression) =
|
||||
primitiveOp1(
|
||||
startOffset, endOffset, context.irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCLEQ,
|
||||
startOffset, endOffset, context.irBuiltIns.booleanNotSymbol, context.irBuiltIns.booleanType, IrStatementOrigin.EXCLEQ,
|
||||
irEquals(arg1, arg2, origin = IrStatementOrigin.EXCLEQ)
|
||||
)
|
||||
|
||||
|
||||
@@ -22,16 +22,20 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.IrWhen
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
|
||||
// TODO rewrite using IR Builders
|
||||
|
||||
fun primitiveOp1(
|
||||
startOffset: Int, endOffset: Int,
|
||||
primitiveOpSymbol: IrSimpleFunctionSymbol,
|
||||
primitiveOpReturnType: IrType,
|
||||
origin: IrStatementOrigin,
|
||||
argument: IrExpression
|
||||
dispatchReceiver: IrExpression
|
||||
): IrExpression =
|
||||
IrUnaryPrimitiveImpl(startOffset, endOffset, primitiveOpSymbol.owner.returnType, origin, primitiveOpSymbol, argument)
|
||||
IrCallImpl(startOffset, endOffset, primitiveOpReturnType, primitiveOpSymbol, primitiveOpSymbol.descriptor, origin = origin).also {
|
||||
it.dispatchReceiver = dispatchReceiver
|
||||
}
|
||||
|
||||
fun primitiveOp2(
|
||||
startOffset: Int, endOffset: Int,
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
@@ -195,7 +196,6 @@ class IrBuiltIns(
|
||||
val throwNpeFun = defineOperator(OperatorNames.THROW_NPE, nothing, listOf())
|
||||
val throwCceFun = defineOperator(OperatorNames.THROW_CCE, nothing, listOf())
|
||||
val throwIseFun = defineOperator(OperatorNames.THROW_ISE, nothing, listOf())
|
||||
val booleanNotFun = defineOperator(OperatorNames.NOT, bool, listOf(bool))
|
||||
val noWhenBranchMatchedExceptionFun = defineOperator(OperatorNames.NO_WHEN_BRANCH_MATCHED_EXCEPTION, nothing, listOf())
|
||||
val illegalArgumentExceptionFun = defineOperator(OperatorNames.ILLEGAL_ARGUMENT_EXCEPTION, nothing, listOf(string))
|
||||
|
||||
@@ -203,7 +203,7 @@ class IrBuiltIns(
|
||||
val eqeq = eqeqFun.descriptor
|
||||
val throwNpe = throwNpeFun.descriptor
|
||||
val throwCce = throwCceFun.descriptor
|
||||
val booleanNot = booleanNotFun.descriptor
|
||||
val booleanNot = builtIns.boolean.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("not"), NoLookupLocation.FROM_BACKEND).single()
|
||||
val noWhenBranchMatchedException = noWhenBranchMatchedExceptionFun.descriptor
|
||||
val illegalArgumentException = illegalArgumentExceptionFun.descriptor
|
||||
|
||||
@@ -212,7 +212,7 @@ class IrBuiltIns(
|
||||
val throwNpeSymbol = throwNpeFun.symbol
|
||||
val throwCceSymbol = throwCceFun.symbol
|
||||
val throwIseSymbol = throwIseFun.symbol
|
||||
val booleanNotSymbol = booleanNotFun.symbol
|
||||
val booleanNotSymbol = symbolTable.referenceSimpleFunction(booleanNot)
|
||||
val noWhenBranchMatchedExceptionSymbol = noWhenBranchMatchedExceptionFun.symbol
|
||||
val illegalArgumentExceptionSymbol = illegalArgumentExceptionFun.symbol
|
||||
|
||||
@@ -262,7 +262,6 @@ class IrBuiltIns(
|
||||
const val EQEQ = "EQEQ"
|
||||
const val EQEQEQ = "EQEQEQ"
|
||||
const val IEEE754_EQUALS = "ieee754equals"
|
||||
const val NOT = "NOT"
|
||||
const val THROW_NPE = "THROW_NPE"
|
||||
const val THROW_CCE = "THROW_CCE"
|
||||
const val THROW_ISE = "THROW_ISE"
|
||||
|
||||
@@ -107,54 +107,6 @@ class IrNullaryPrimitiveImpl(
|
||||
IrNullaryPrimitiveImpl(startOffset, endOffset, type, newOrigin, newCallee)
|
||||
}
|
||||
|
||||
class IrUnaryPrimitiveImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: IrType,
|
||||
origin: IrStatementOrigin?,
|
||||
symbol: IrFunctionSymbol
|
||||
) : IrPrimitiveCallBase(startOffset, endOffset, type, origin, symbol, 1),
|
||||
IrCallWithShallowCopy {
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: IrType,
|
||||
origin: IrStatementOrigin?,
|
||||
symbol: IrFunctionSymbol,
|
||||
argument: IrExpression
|
||||
) : this(startOffset, endOffset, type, origin, symbol) {
|
||||
this.argument = argument
|
||||
}
|
||||
|
||||
lateinit var argument: IrExpression
|
||||
|
||||
override fun getValueArgument(index: Int): IrExpression? {
|
||||
return when (index) {
|
||||
ARGUMENT0 -> argument
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun putValueArgument(index: Int, valueArgument: IrExpression?) {
|
||||
when (index) {
|
||||
ARGUMENT0 -> argument = valueArgument ?: throw AssertionError("Primitive call $descriptor argument is null")
|
||||
else -> throw AssertionError("Primitive call $descriptor: no such argument index $index")
|
||||
}
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
argument.accept(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
argument = argument.transform(transformer, data)
|
||||
}
|
||||
|
||||
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: IrFunctionSymbol, newSuperQualifier: IrClassSymbol?): IrCall =
|
||||
IrUnaryPrimitiveImpl(startOffset, endOffset, type, newOrigin, newCallee)
|
||||
}
|
||||
|
||||
class IrBinaryPrimitiveImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
|
||||
Reference in New Issue
Block a user